Подтвердить что ты не робот

Как удалить только исходный элемент, а не его дочерние элементы в JavaScript?

Скажем:

<div>
some text
  <div class="remove-just-this">
  <p>foo</p>
  <p>bar</p>
  some text node here
  </div>
some text
</div>

:

<div>
some text
  <p>foo</p>
  <p>bar</p>
  some text node here
some text
</div>

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

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

Ответ 3

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

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

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);

Ответ 4

 $('.remove-just-this > *').unwrap()

Ответ 5

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

$('.remove-just-this').contents().unwrap();

Ответ 6

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

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

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

Ответ 7

И, поскольку вы тоже пытались в 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

Ответ 8

Используйте современные 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 - это оператор спрединга, передающий каждый элемент массива в качестве параметра

Ответ 9

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

def remove_node(doc, element):
    """ removes a specific node, adding its children in its place
    """
    fragment = doc.createDocumentFragment()
    while element.firstChild:
        fragment.appendChild(element.firstChild)

    parent = element.parentNode
    parent.insertBefore(fragment, element)
    parent.removeChild(element)

Ответ 10

Я искал лучший ответ по производительности во время работы над важной DOM.

Ответ на вопрос о том, что использование javascript было бы лучше всего, было бы лучше.

Я выполнил следующие тесты времени выполнения на 5000 строк и 400 000 символов с составной композицией DOM внутри раздела для удаления. Я использую ID вместо класса для удобства при использовании javascript.

Использование $.unwrap()

$('#remove-just-this').contents().unwrap();

201.237ms

Использование $.replaceWith()

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

156.983ms

Использование DocumentFragment в javascript

var element = document.getElementById('remove-just-this');
var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);

147.211ms

Заключение

Производительность, даже при относительно большой структуре DOM, разница между использованием jQuery и javascript невелика. Удивительно $.unwrap() является наиболее дорогостоящим, чем $.replaceWith(). Тесты были выполнены с помощью jQuery 1.12.4.

Ответ 11

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

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });