Jak usunąć tylko element nadrzędny, a nie jego elementy potomne w JavaScript?

Powiedzmy:

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

Do tego:

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

Zastanawiałem się nad Mootools, jQuery, a nawet (raw) JavaScript, ale nie mogłem zrozumieć, jak to zrobić.

Author: TallOrderDev, 2008-10-04

11 answers

Używając jQuery możesz to zrobić:

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

Szybkie linki do dokumentacji:

  • spis treści( ) : jQuery
  • ( zawartość : [String | Element | jQuery] ) : jQuery
 125
Author: jk.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-17 02:05:25

Metoda niezależna od biblioteki polega na wstawieniu przed sobą wszystkich węzłów potomnych elementu, który ma zostać usunięty (co domyślnie usuwa je ze starej pozycji), przed usunięciem:

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

nodeToBeRemoved.parentNode.removeChild(nodeToBeRemoved);

Spowoduje to przeniesienie wszystkich węzłów potomnych w odpowiednie miejsce w odpowiedniej kolejności.

 35
Author: Jonny Buchanan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-04 12:46:42

Powinieneś upewnić się, że robisz to z DOM, a nie innerHTML (i jeśli używasz rozwiązania jQuery dostarczonego przez jk, upewnij się, że przesuwa węzły DOM zamiast używać innerHTML wewnętrznie), w celu zachowania rzeczy takich jak procedury obsługi zdarzeń.

Moja odpowiedź jest podobna do insin, ale będzie działać lepiej dla dużych struktur (dołączanie każdego węzła osobno może być opodatkowane od przerysowań, gdzie CSS musi być ponownie zastosowany dla każdego appendChild; z DocumentFragment, dzieje się to tylko raz, ponieważ nie jest widoczne do czasu po jego dzieci są dołączane i jest dodawany do dokumentu).

var fragment = document.createDocumentFragment();
while(element.firstChild) {
    fragment.appendChild(element.firstChild);
}
element.parentNode.replaceChild(fragment, element);
 31
Author: eyelidlessness,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-08 20:17:54
 $('.remove-just-this > *').unwrap()
 25
Author: campino2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-19 13:55:19

Bardziej elegancki sposób jest

$('.remove-just-this').contents().unwrap();
 16
Author: yunda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-01 16:22:00

Użyj nowoczesnego 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) is valid ES5

...array jest operatorem rozproszonym, przekazującym każdy element tablicy jako parametr

 3
Author: Gibolt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-13 18:56:29

Niezależnie od używanej biblioteki musisz sklonować wewnętrzny div przed usunięciem zewnętrznego div z DOM. Następnie musisz dodać sklonowany wewnętrzny div do miejsca w DOM, w którym znajdował się zewnętrzny div. Więc kroki są:

  1. Zapisz odniesienie do zewnętrznego rodzica div w zmiennej
  2. skopiuj wewnętrzny div do innej zmiennej. Można to zrobić w szybki i brudny sposób, zapisując innerHTML wewnętrznego div do zmiennej lub można skopiować wewnętrzny węzeł drzewa rekurencyjnie przez węzeł.
  3. wywołanie removeChild na zewnętrznym rodzicu div z zewnętrznym div jako argumentem.
  4. Wstaw skopiowaną zawartość wewnętrzną do zewnętrznego rodzica div w prawidłowej pozycji.

Niektóre biblioteki zrobią to za ciebie, ale coś podobnego do powyższego będzie się działo pod maską.

 2
Author: domgblackwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-04 11:06:24

A ponieważ próbowałeś również w mootools, oto rozwiązanie w mootools.

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

Zauważ, że to zupełnie nieprzetestowane, ale pracowałem już z mootools i powinno działać.

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

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

 2
Author: tj111,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-22 21:30:13

Jeśli chcesz zrobić to samo w piżamie, oto jak to zrobić. działa świetnie(dziękuję za powieki). udało mi się zrobić odpowiedni edytor rich text, który poprawnie robi style bez bałaganu, dzięki temu.

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)
 0
Author: user362834,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-24 11:57:45

Szukałem najlepszej odpowiedzi pod względem wydajności podczas pracy nad ważnym DOM.

Eyeless ' s odpowiedź wskazywała, że za pomocą javascript występy będą najlepsze.

Wykonałem następujące testy czasu wykonania na 5000 linii i 400 000 znaków z złożoną kompozycją DOM wewnątrz sekcji do usunięcia. Używam ID zamiast klasy z wygodnego powodu podczas korzystania z javascript.

Za pomocą $.rozpakuj()

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

201.237 ms

Używając $./ align = "left" / ()

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

156.983 ms

Korzystanie z DocumentFragment w 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.211 ms

Wniosek

Pod względem wydajności, nawet na stosunkowo dużej strukturze DOM, różnica między używaniem jQuery i javascript nie jest ogromna. Zaskakująco {[3] } jest najbardziej kosztowne niż $.replaceWith(). Testy zostały wykonane z jQuery 1.12.4.

 0
Author: maxime_039,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-17 13:14:49

Jeśli masz do czynienia z wieloma wierszami, jak to było w moim przypadku użycia, prawdopodobnie lepiej będzie z czymś w tym stylu:

 $(".card_row").each(function(){
        var cnt = $(this).contents();
        $(this).replaceWith(cnt);
    });
 0
Author: Iso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-15 12:11:36