Jak powinienem przejść do usuwania wszystkich elementów potomnych węzła DOM w JavaScript?
Powiedz, że mam następujący (brzydki) kod HTML:
<p id="foo">
<span>hello</span>
<div>world</div>
</p>
I łapię węzeł, który chcę:
var myNode = document.getElementById("foo");
Jak mogę usunąć dzieci foo
, aby po prostu <p id="foo"></p>
zostały?
Czy mogę po prostu zrobić:
myNode.childNodes = new Array();
czy powinienem używać jakiejś kombinacji removeElement
?
Chciałbym, aby odpowiedź była prosta DOM; dodatkowe punkty, jeśli podasz także odpowiedź w jQuery wraz z odpowiedzią tylko dla DOM.
javascript
dom
Polaris878
źródło
źródło
innerHTML = ''
jest wolniejsze, ale nie sądzę, żeby było „złe”. Wszelkie roszczenia dotyczące wycieków pamięci należy poprzeć dowodami.Aktualnie akceptowana odpowiedź jest błędna, jeśli chodzi o
innerHTML
spowolnienie (przynajmniej w IE i Chrome), jak słusznie wspomniano m93a.Chrome i FF są znacznie szybsze przy użyciu tej metody (która zniszczy załączone dane jquery):
w odległej sekundzie dla FF i Chrome, a najszybszy w IE:
InnerHTML nie niszczy programów obsługi zdarzeń ani nie niszczy odniesień do jquery , jest również zalecane jako rozwiązanie tutaj: https://developer.mozilla.org/en-US/docs/Web/API/Element.innerHTML .
Najszybszą metodą manipulacji DOM (nadal wolniejszą niż dwie poprzednie) jest usunięcie zakresu, ale zakresy nie są obsługiwane do IE9.
Inne wymienione metody wydają się być porównywalne, ale o wiele wolniejsze niż innerHTML, z wyjątkiem wartości odstającej, jquery (1.1.1 i 3.1.1), która jest znacznie wolniejsza niż cokolwiek innego:
Dowody tutaj:
http://jsperf.com/innerhtml-vs-removechild/167http://jsperf.com/innerhtml-vs-removechild/300https://jsperf.com/remove-all-child-elements-of-a- dom-node-in-javascript (Nowy adres URL do ponownego uruchomienia jsperf, ponieważ edycja starego adresu URL nie działa)„Pętla na test” Jsperfa często jest rozumiana jako „per-iteracja”, a tylko pierwsza iteracja ma węzły do usunięcia, więc wyniki są bez znaczenia, w momencie publikacji testy w tym wątku były nieprawidłowo skonfigurowane.
źródło
jQuery.cache
, powodując wyciek pamięci, ponieważ jedynym dostępnym odniesieniem do zarządzania tymi danymi były elementy, które właśnie zniszczyłeś.cloneNode
wyłącza kontener, co oznacza, że odniesienia do kontenera nie są zachowywane (kwerendy lub w inny sposób). Pamięć podręczna Jquery może sprawić, że warto użyć jquery do usunięcia elementów, jeśli masz dołączone dane jquery. Mam nadzieję, że w pewnym momencie przejdą na WeakMaps . Czyszczenie (a nawet istnienie) $ .cache nie wydaje się być oficjalnie udokumentowane.Korzystaj z nowoczesnego Javascript z
remove
!Jest to nowszy sposób zapisywania usuwania węzłów w ES5. Jest to waniliowy JS i czyta się znacznie ładniej niż poprzednie wersje.
Większość użytkowników powinna mieć nowoczesne przeglądarki lub w razie potrzeby można dokonać transpozycji w dół.
Obsługa przeglądarki - 95%, grudzień 2019
źródło
while (parent.firstChild) { parent.removeChild(parent.firstChild); }
pętli. developer.mozilla.org/en-US/docs/Web/API/ParentNode/children developer.mozilla.org/en-US/docs/Web/API/Node/childNodeswhile (parent.firstChild && !parent.firstChild.remove());
[...parent.childNodes].forEach(el => el.remove());
while (selectElem.firstElementChild) { selectElem.firstElementChild.remove(); }
Jeśli istnieje szansa, że masz potomków dotkniętych przez jQuery, musisz użyć metody, która wyczyści dane jQuery.
JQuery
.empty()
Sposób zapewnia, że wszystkie dane związane z elementami jQuery usuwany zostaną oczyszczone.Jeśli po prostu zastosujesz
DOM
metody usuwania dzieci, dane te pozostaną.źródło
while ( myNode.firstChild ) {
while(fc = myNode.firstChild){ myNode.removeChild(fc); }
Jeśli używasz jQuery:
Jeśli nie:
źródło
Najszybszy...
Podziękowania dla Andreya Lushnikova za jego link do strony jsperf.com (fajna strona!).
EDYCJA: żeby było jasne, nie ma różnicy w wydajności między Chrome między firstChild a lastChild. Najlepsza odpowiedź pokazuje dobre rozwiązanie dla wydajności.
źródło
Jeśli chcesz mieć tylko węzeł bez jego elementów potomnych, możesz również wykonać jego kopię w następujący sposób:
Zależy od tego, co próbujesz osiągnąć.
źródło
parent.replaceChild(cloned, original)
? Może to być szybsze niż usuwanie dzieci jeden po drugim i powinno działać na wszystkim, co obsługuje DOM (a więc na każdym typie dokumentu XML, w tym SVG). Ustawienie innerHTML może być również szybsze niż usuwanie dzieci jeden po drugim, ale to nie działa na niczym innym niż dokumenty HTML. Powinien to sprawdzić jakiś czas.addEventListener
.Oto inne podejście:
źródło
To jest jak tekst wewnętrzny, z wyjątkiem standardowego. Jest nieco wolniejszy niż
removeChild()
, ale jest łatwiejszy w użyciu i nie zrobi dużej różnicy w wydajności, jeśli nie masz zbyt wielu rzeczy do usunięcia.źródło
W odpowiedzi na DanMan, Maarten i Matt. Klonowanie węzła w celu ustawienia tekstu jest rzeczywiście realnym sposobem w moich wynikach.
Działa to również w przypadku węzłów spoza domeny, które zwracają wartość null podczas próby uzyskania dostępu do elementu parentNode. Ponadto, jeśli musisz być bezpieczny, węzeł jest pusty przed dodaniem treści, jest to naprawdę pomocne. Rozważ przypadek użycia poniżej.
Uważam, że ta metoda jest bardzo przydatna podczas zastępowania łańcucha wewnątrz elementu, jeśli nie jesteś pewien, co zawiera węzeł, zamiast martwić się, jak posprzątać bałagan, zacznij od nowa.
źródło
Oto, co zwykle robię:
I voila, później możesz opróżnić dowolny element dom za pomocą:
źródło
domEl.innerHTML = ""
jest słaba i uważana za złą praktykęMożna to osiągnąć na kilka sposobów:
Najszybszy ():
Alternatywy (wolniej):
Benchmark z sugerowanymi opcjami
źródło
Spowoduje to usunięcie wszystkich węzłów w elemencie.
źródło
innerText jest zwycięzcą! http://jsperf.com/innerhtml-vs-removechild/133 . We wszystkich poprzednich testach wewnętrzna domena węzła nadrzędnego była usuwana przy pierwszej iteracji, a następnie innerHTML lub removeChild, gdzie zastosowano do pustej div.
źródło
innerText
jest zastrzeżoną rzeczą stwardnienia rozsianego chociaż. Tylko mówię.box
że nie jest dostępny jako var, ale poprzez wyszukiwanie DOM na podstawie identyfikatora, a ponieważwhile
pętla powoduje, że to wolne połączenie jest wielokrotnie karane.Najprostszy sposób usuwania węzłów potomnych węzła za pomocą Javascript
źródło
widziałem ludzi, którzy:
wtedy ktoś powiedział używając
el.lastNode
jest szybszeMyślę jednak, że jest to najszybszy:
co myślisz?
ps: ten temat był dla mnie ratunkiem. mój dodatek Firefox został odrzucony, ponieważ użyłem innerHTML. To był nawyk przez długi czas. to foudn to. i faktycznie zauważyłem różnicę prędkości. po załadowaniu odczekiwanie na aktualizację innerhtml trwało chwilę, jednak addElement działał natychmiast!
źródło
for (var i=0...
jednak tego. Ale oto, co dostałem, kiedy przeprowadziłem te testy: i.imgur.com/Mn61AmI.png, więc w tych trzech testach firstNode był szybszy niż lastNode i innerHTML, co jest naprawdę fajneKorzystanie z pętli zasięgu jest dla mnie najbardziej naturalne:
Według moich pomiarów w Chrome i Firefox jest około 1,3 razy wolniejszy. W normalnych okolicznościach może to nie będzie miało znaczenia.
źródło
źródło
Ogólnie JavaScript używa tablic do odwoływania się do list węzłów DOM. Będzie to działać dobrze, jeśli masz interes w tym, aby zrobić to za pomocą tablicy HTMLElements. Warto również zauważyć, ponieważ używam odwołania do tablicy zamiast proto JavaScript, powinno to działać w dowolnej przeglądarce, w tym IE.
źródło
Dlaczego nie zastosujemy tutaj najprostszej metody „usuń” zapętloną wewnątrz.
źródło
Właśnie widziałem, jak ktoś wspomniał o tym pytaniu w innym i pomyślał, że dodam metodę, której jeszcze nie widziałem:
Funkcja czyszczenia polega na pobieraniu elementu i używaniu węzła nadrzędnego do zastąpienia się kopią bez elementów potomnych. Niewielki wzrost wydajności, jeśli element jest rzadki, ale gdy element ma kilka węzłów, wzrost wydajności jest realizowany.
źródło
Podejście tylko funkcjonalne:
„childNodes” w domChildren poda nodeList bezpośrednich elementów potomnych, który jest pusty, gdy nie zostaną znalezione. Aby zmapować listę nodeList, domChildren konwertuje ją na tablicę. domEmpty mapuje funkcję domRemove na wszystkie elementy, które ją usuwają.
Przykładowe użycie:
usuwa wszystkie dzieci z elementu ciała.
źródło
Inne sposoby w jQuery
źródło
.empty()
metodę,$("#foo").empty()
wystarczyłobypo prostu tylko IE:
true
- oznacza głębokie usunięcie - co oznacza, że wszystkie dzieci są również usuwaneźródło
Najłatwiejszy sposób:
źródło
container.innerHTML = null
aby Internet Explorer wyświetlał tekstnull
. Powiedziałbym, że to tak naprawdę nie usuwa dzieci.prosty i szybki w użyciu dla pętli !!
to nie zadziała w
<span>
tagu!źródło
<span>
taguJeśli chcesz coś w to włożyć
div
,innerHTML
to prawdopodobnie lepiej.Mój przykład:
Jeśli użyję metody
.firstChild
lub.lastChild
,displayHTML()
funkcja nie będzie działać później, ale nie będzie problemu z tą.innerHTML
metodą.źródło
To jest czysty skrypt javascript Nie używam jQuery, ale działa we wszystkich przeglądarkach, nawet IE i jest bardzo prosty do zrozumienia
źródło
z jQuery:
źródło
$('#foo').children().remove()
o wiele bardziej logiczne