Как удалить только родительский элемент, а не его дочерние элементы в JavaScript? - PullRequest
84 голосов
/ 04 октября 2008

Допустим,

<div>
  pre text
  <div class="remove-just-this">
    <p>child foo</p>
    <p>child bar</p>
    nested text
  </div>
  post text
</div>

к этому:

<div>
  pre text
  <p>child foo</p>
  <p>child bar</p>
  nested text
  post text
</div>

Я выяснил, используя Mootools, jQuery и даже (необработанный) JavaScript, но не смог понять, как это сделать.

Ответы [ 12 ]

129 голосов
/ 04 октября 2008

Используя jQuery , вы можете сделать это:

var cnt = $(".remove-just-this").contents();
$(".remove-just-this").replaceWith(cnt);

Быстрые ссылки на документацию:

36 голосов
/ 04 октября 2008

Независимый от библиотеки метод состоит в том, чтобы вставить все дочерние узлы удаляемого элемента перед собой (который неявно удаляет их из прежней позиции), прежде чем удалить его:

while (nodeToBeRemoved.firstChild)
{
    nodeToBeRemoved.parentNode.insertBefore(nodeToBeRemoved.firstChild,
                                            nodeToBeRemoved);
}

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

Это переместит все дочерние узлы в правильное место в правильном порядке.

32 голосов
/ 07 октября 2008

Вы должны убедиться, что делаете это с DOM, а не с innerHTML (и если вы используете решение jQuery, предоставляемое jk, убедитесь, что оно перемещает узлы DOM, а не с помощью innerHTML внутри), чтобы сохранить такие вещи, как обработчики событий.

Мой ответ во многом похож на insin, но он будет работать лучше для больших структур (добавление каждого узла в отдельности может облагаться налогом на перерисовки, где CSS нужно повторно применять для каждого appendChild; с DocumentFragment, это происходит только один раз поскольку он не отображается до тех пор, пока все его дочерние элементы не будут добавлены и не добавлены в документ).

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);
26 голосов
/ 19 октября 2011
 $('.remove-just-this > *').unwrap()
17 голосов
/ 01 апреля 2016

Более элегантный способ это

$('.remove-just-this').contents().unwrap();
5 голосов
/ 13 августа 2017

Используйте современный JS!

const node = document.getElementsByClassName('.remove-just-this')[0];
node.replaceWith(...node.childNodes); // or node.children, if you don't want textNodes

oldNode.replaceWith(newNode) действительно ES5

...array - оператор распространения, передающий каждый элемент массива в качестве параметра

2 голосов
/ 23 октября 2008

И, так как вы пробовали и в mootools, вот решение для mootools.

var children = $('remove-just-this').getChildren();
children.replaces($('remove-just-this');

Обратите внимание, что это полностью не проверено, но я работал с mootools раньше, и он должен работать.

http://mootools.net/docs/Element/Element#Element:getChildren

http://mootools.net/docs/Element/Element#Element:replaces

2 голосов
/ 04 октября 2008

Какую бы библиотеку вы не использовали, вы должны клонировать внутренний div перед удалением внешнего div из DOM. Затем вы должны добавить клонированный внутренний div в то место в DOM, где находился внешний div. Итак, шаги:

  1. Сохранить ссылку на родительский элемент внешнего div в переменной
  2. Скопируйте внутренний div в другую переменную. Это можно сделать быстрым и грязным способом, сохранив innerHTML внутреннего div в переменной или вы можете скопировать внутреннее дерево рекурсивно узел за узлом.
  3. Вызовите removeChild родителя внешнего div с внешним div в качестве аргумента.
  4. Вставьте скопированное внутреннее содержимое в родительский элемент внешнего div в правильном положении.

Некоторые библиотеки сделают для вас это частично или полностью, но что-то подобное будет происходить под капотом.

0 голосов
/ 11 марта 2019

Заменить div его содержимым:

const wrapper = document.querySelector('.remove-just-this');
wrapper.outerHTML = wrapper.innerHTML;
<div>
  pre text
  <div class="remove-just-this">
    <p>child foo</p>
    <p>child bar</p>
    nested text
  </div>
  post text
</div>
0 голосов
/ 15 мая 2017

Если вы имеете дело с несколькими строками, как это было в моем случае, вам, вероятно, лучше что-то вроде этого:

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...