2010-06-21 9 views
131

Powiedzmy, że określenie elementuJak sprawdzić, czy element jQuery znajduje się w DOM?

$foo = $('#foo'); 

a potem zadzwonić

$foo.remove() 

od jakiegoś zdarzenia. Moje pytanie brzmi: jak mogę sprawdzić, czy $ foo zostało usunięte z DOM, czy nie? Zauważyłem, że działa $foo.is(':hidden'), ale to oczywiście również zwróci true, jeśli po prostu zadzwoniłem pod numer $foo.hide().

Odpowiedz

215

Jak to:

if (!jQuery.contains(document, $foo[0])) { 
    //Element is detached 
} 

ten będzie nadal działać, jeśli jeden z rodziców elementu została usunięta (w tym przypadku sam element będzie nadal mieć rodzica).

+0

+1, która jest zgrabna :) –

+12

robienie '$ foo.closest (document.documentElement)' jest szybsze (jeśli ktokolwiek dba o http://jsperf.com/jquery-element-in-dom) – urraka

+47

@PerroAzul: Znalazłem _ znacznie szybszą alternatywę: http://jsperf.com/jquery-element-in-dom/2 – SLaks

4

Właśnie uświadomiłem sobie odpowiedź jak pisałem moje pytanie: Call

$foo.parent() 

Jeśli $f00 została usunięta z DOM, następnie $foo.parent().length === 0. W przeciwnym razie jego długość będzie wynosić co najmniej 1.

[Edytuj: nie jest to całkowicie poprawne, ponieważ usunięty element może nadal mieć element nadrzędny; na przykład, jeśli usuniesz <ul>, każde z jego potomków będzie nadal mieć rodzica. Zamiast tego użyj odpowiedzi SLaks.

+1

... chyba że usunięto węzeł nie był jedynakiem –

+0

@ Álvaro - Dlaczego miałbym to znaczenie? – user113716

+0

@patrick: Czy coś mi umknęło? Co możesz zapewnić, jeśli wartość $ foo.parent(). Jest większa od zera? –

21

Jak ow ten sposób:

$element.parents('html').length > 0 
+0

Myślę, że jest o wiele szybszy –

+13

W rzeczywistości jest najwolniejszy: http://jsperf.com/jquery-element-in-dom/60 – suda

0

Zgadzam się z komentarzem Perro za. Można również zrobić tak:

$foo.parents().last().is(document.documentElement); 
4

Ponieważ jestem w stanie odpowiedzieć w komentarzu (zbyt niska karma chyba), tutaj jest pełna odpowiedź. Najszybszym sposobem jest łatwe rozwinięcie sprawdzania jQuery dla obsługi przeglądarki i zredukowanie stałych współczynników do minimum.

Jak widać również tu - http://jsperf.com/jquery-element-in-dom/28 - kod powinien wyglądać następująco:

var isElementInDOM = (function($) { 
    var docElt = document.documentElement, find, 
     contains = docElt.contains ? 
     function(elt) { return docElt.contains(elt); } : 

     docElt.compareDocumentPosition ? 
      function(elt) { 
      return docElt.compareDocumentPosition(elt) & 16; 
      } : 
      ((find = function(elt) { 
       return elt && (elt == docElt || find(elt.parentNode)); 
      }), function(elt) { return find(elt); }); 

    return function(elt) { 
    return !!(elt && ((elt = elt.parent) == docElt || contains(elt))); 
    }; 
})(jQuery); 

to semantycznie równoważne jQuery.contains (document.documentElement, elt [0]).

0

Dlaczego nie tylko: if($('#foo').length === 0)...?

+0

@stevematdavies Pytanie brzmi "jak sprawdzić, czy element w danym obiekcie jQuery jest w DOM ", a nie" jak sprawdzić, czy element pasujący do danego łańcucha selektora znajduje się w DOM. " –

+0

@ TrevorBurnham: w pełni uczciwość, ponowne zapytanie za pomocą selektora, który został użyty do utworzenia '$ foo', i sprawdzenie, czy ponowne zapytanie pasowało do jakiegokolwiek elementu, wydaje się realnym rozwiązaniem problemu w wielu scenariuszach.Może nawet * szybciej * niż niektóre inne rozwiązania, ponieważ zarówno jQuery, jak i przeglądarki optymalizują niektóre selektory (takie jak ID). – Matt

+0

@Matt $ foo może być elementem w pamięci odłączonym od DOM i może istnieć element z dopasowanym selektorem w DOM. Osoby szukające odpowiedzi na to pytanie prawdopodobnie chcą sprawdzić, czy jest ono w DOM, czy nie. Ktoś, kto pracuje w takich rzeczach, oczywiście wie, jak zapytać DOM. –

0
if($foo.nodeType){ element is node type} 
0
jQuery.fn.isInDOM = function() { 
    if (this.length == 1) { 
     var element = this.get(0); 
     var rect = element.getBoundingClientRect(); 
     if (rect.top + rect.bottom + rect.width + rect.height + rect.left + rect.right == 0) 
     return false; 
     return true; 
    } 
    return false; 
}; 
0

lubiłem tego podejścia. Bez jQuery i bez wyszukiwania DOM. Najpierw znajdź najlepszego rodzica (przodka). Następnie sprawdź, czy to jest documentElement.

function ancestor(HTMLobj){ 
    while(HTMLobj.parentElement){HTMLobj=HTMLobj.parentElement} 
    return HTMLobj; 
} 
function inTheDOM(obj){ 
    return ancestor(obj)===document.documentElement; 
} 
0

Prawdopodobnie najbardziej performatywna sposobem jest:

document.contains(node); // boolean 

To również działa z jQuery:

document.contains($element[0]); // var $element = $("#some-element") 
document.contains(this[0]); // in contexts like $.each(), `this` is the jQ object 

Źródło z MDN

Uwaga:

+0

Jak ktoś jeszcze spojrzał na tę odpowiedź? Świetna odpowiedź +1 (sugerowałem wydanie, dziękuję) –

Powiązane problemy