Bir jQuery öğesinin DOM'da olup olmadığını nasıl kontrol ederim?


148

Diyelim ki bir eleman tanımladım

$foo = $('#foo');

ve sonra ararım

$foo.remove()

bazı olaylardan. Sorum şu, $ foo'nun DOM'dan kaldırılıp kaldırılmadığını nasıl kontrol ederim? Bunun $foo.is(':hidden')işe yaradığını buldum , ancak sadece ararsam bu da tabii ki doğru olur $foo.hide().

Yanıtlar:


239

Bunun gibi:

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

Bu, öğenin üst öğelerinden biri kaldırılsa bile çalışacaktır (bu durumda öğenin kendisinin de bir üst öğesi olacaktır).


14
yapmak $foo.closest(document.documentElement)daha hızlıdır (eğer kimse umursuyorsa jsperf.com/jquery-element-in-dom )
urraka

48
@PerroAzul: Çok daha hızlı bir alternatif buldum : jsperf.com/jquery-element-in-dom/2
SLaks

3
Performans, bu yöntemle ilgili acil endişemdi, @SLaks kriterlerini bağladığınız için teşekkürler. Yani $.contains(document.documentElement, $foo.get(0))en hızlı yol bu gibi görünüyor .
Christof

12
Bunu yapmanın, sözdizimsel olarak daha okunaklı olan saf bir DOM yolu var ve performans açısından çok benzer olduğunu düşünüyorum:document.contains($foo[0])
Joel Cross

4
Bütün bu performans konuşmaları ...? Kıyaslamalar, bir yöntemi 15 mikrosaniye, diğerinin 0.15 mikrosaniye sürdüğünü göstermektedir. Ama gerçekten, kimin umurunda - bunu yüz bin kez yapmadığınız sürece hiçbir fark görmeyeceksiniz. Ve jQuery veya JavaScript motoru optimize edilirse her şey değişebilir.Sadece size ve gelecekte kodunuzu korumak zorunda olanlar için daha iyi okuyan yöntemi kullanın.
James


5

Yorum olarak yanıt veremediğim için (sanırım çok düşük karma), işte tam bir yanıt. En hızlı yol, tarayıcı desteği için jQuery kontrolünü açmak ve sabit faktörleri minimuma indirmektir.

Burada da görüldüğü gibi - http://jsperf.com/jquery-element-in-dom/28 - kod şöyle görünecektir:

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);

Bu anlamsal olarak jQuery.contains'e (document.documentElement, elt [0]) eşdeğerdir.


4

Sorumu yazarken bir cevabın farkına vardım: Ara

$foo.parent()

Eğer $f00o zaman, DOM kaldırıldı $foo.parent().length === 0. Aksi takdirde uzunluğu en az 1 olacaktır.

[Düzenleme: Bu tamamen doğru değildir, çünkü kaldırılan bir öğenin hala bir ebeveyni olabilir; örneğin, a'yı kaldırırsanız <ul>, alt <li>öğelerinin her birinin hala bir ebeveyni olacaktır. Bunun yerine SLaks'ın cevabını kullanın.


2
... kaldırılan düğüm tek çocuk değilse
Álvaro González

@ Álvaro - Bu neden önemli?
user113716

@patrick: Bir şey mi kaçırdım? $ Foo.parent (). Uzunluğu sıfırdan büyükse ne temin edebilirsiniz?
Álvaro González

@ Álvaro - OP, DOM'den $fookaldırıldığından emin olmak için test ediyor . Başarıyla kaldırıldıysa, artık bir üst öğesi olmayacaktır. Bu nedenle $foo.parent().length === 0, kaldırma işleminin başarılı olduğu anlamına gelir.
user113716

1
$ foo.closest ("body") bu teknik için bir düzeltme olacaktır
georgephillips


1

Bu yaklaşımı beğendim. JQuery ve DOM araması yok. Önce en üstteki ebeveyni (atayı) bulun. Sonra bunun documentElement olup olmadığına bakın.

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

1

Ebeveynleri yinelemek yerine, öğe dom'dan ayrıldığında tümü sıfır olan sınırlayıcı rect'i elde edebilirsiniz.

function isInDOM(element) {
    var rect=element.getBoundingClientRect();
    return (rect.top || rect.bottom || rect.height || rect.width)?true:false;
}

Sıfır genişlik ve yükseklik öğesinin sıfır üst ve sıfır soldaki kenar durumunu işlemek istiyorsanız, belgeye kadar üst öğeleri yineleyerek iki kez kontrol edebilirsiniz. gövde


Bu kod parçacığı sorunu çözebilir ancak soruyu neden veya nasıl yanıtladığını açıklamaz. Lütfen kodunuz için bir açıklamaya yer gerçekten Yayınınızla kalitesini artırmak için yardımcı olarak,. Gelecekte okuyucular için soruyu yanıtlayacağınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceklerini unutmayın. İşaretleyiciler / gözden geçirenler: Bunun gibi salt kod yanıtları için, olumsuz oy verin, silmeyin!
Luca Kiebel

Bu aynı zamanda gizli öğeleri "DOM'da değil" olarak tanımıyor mu? örneğin display: none, boundingRect'i de olmayan bir öğe
Philipp

0

Perro'nun yorumuna katılıyorum. Şu şekilde de yapılabilir:

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

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;
};

-1

Neden sadece: if( $('#foo').length === 0)...?


@stevematdavies Soru, "belirli bir jQuery nesnesindeki bir öğenin DOM'da olup olmadığının nasıl test edileceği" değil, "belirli bir seçici dizeyle eşleşen bir öğenin DOM'da olup olmadığının nasıl test edileceği" dir.
Trevor Burnham

@TrevorBurnham: Doğrusu, oluşturmak için kullanılan seçiciyi kullanarak yeniden sorgulama $foove yeniden sorgulamanın herhangi bir öğeyle eşleşip eşleşmediğini kontrol etme, birçok senaryoda soruna uygun bir çözüm gibi görünüyor. Hem jQuery'nin hem de tarayıcıların belirli seçicileri (örneğin kimliğe göre) optimize etme şekli nedeniyle diğer çözümlerin bazılarından daha hızlı olabilir .
Matt

@Matt $ foo, DOM'dan ayrılmış bellekte bir öğe olabilir ve DOM'da eşleşen seçiciye sahip bir öğe olabilir. Bu sorunun cevabını arayan kişiler muhtemelen bunun DOM'da olup olmadığını kontrol etmek istiyor. Bunun gibi şeylerde çalışan birinin DOM'u nasıl sorgulayacağını biliyor.
TJ

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.