jQuery要素がDOMにあるかどうかを確認するにはどうすればよいですか?


147

要素を定義するとしましょう

$foo = $('#foo');

そして私は電話します

$foo.remove()

いくつかのイベントから。私の質問は、$ fooがDOMから削除されたかどうかを確認するにはどうすればよいですか?私はそれが$foo.is(':hidden')機能することを発見しましたが、もちろん、単にを呼び出し$foo.hide()ただけでもtrueを返します。

回答:


238

このような:

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

これは、要素の親の1つが削除された場合でも機能します(その場合、要素自体にはまだ親があります)。


14
実行$foo.closest(document.documentElement)はより高速です(誰かがjsperf.com/jquery-element-in-domを気にしている場合
urraka

48
@PerroAzul:私が見つけたずっと速く代替:jsperf.com/jquery-element-in-dom/2
SLaks

3
ベンチマーク@SLaksをリンクしていただきありがとうございます。だから、それが$.contains(document.documentElement, $foo.get(0))最速の方法のように見えます。
Christof、2015年

10
そこ構文的に読みやすく、これを行うには、純粋な-DOMの方法は、ある、と私はパフォーマンスの面で非常によく似た想像:document.contains($foo[0])
ジョエル・クロス

3
このパフォーマンスの話はすべて...?ベンチマークは、15マイクロ秒かかる方法と0.15マイクロ秒かかる方法を示しています。しかし、実際には、誰が気にしますか。10万回実行しない限り、違いに気付くことはありません。そして、jQueryまたはJavaScriptエンジンが最適化されると、すべてが変化する可能性があります。将来、コードを保守する必要がある人にとって、読みやすい方法を使用するだけです。
ジェームズ


5

質問を入力しているときに答えがわかりました:電話

$foo.parent()

場合は$f00、その後、DOMから削除されました$foo.parent().length === 0。それ以外の場合、その長さは少なくとも1になります。

[編集:削除された要素は親を持つことができるため、これは完全に正しくはありません。たとえば、を削除しても<ul>、その子にはそれぞれ<li>親があります。代わりにSLaksの回答を使用してください。


2
...削除したノードが唯一の子ではなかった場合を除き
アルバロ・ゴンサレス

@Álvaro-なぜそれが問題になるのですか?
user113716 2010年

@patrick:私は何かを見逃しましたか?$ foo.parent()。lengthがゼロより大きい場合、何を保証できますか?
アルバロ・ゴンサレス

@Álvaro-OPは$fooDOMから削除されたことを確認するためにテストしています。正常に削除された場合、親要素はなくなります。したがって$foo.parent().length === 0、削除が成功したことを意味します。
user113716 2010年

1
$ foo.closest( "body")は、この手法の修正になるでしょう
georgephillips 2013年

4

コメントとして返信できないので(カルマが少なすぎると思います)、ここで完全な返信を示します。最速の方法は、ブラウザーサポートのjQueryチェックを展開し、一定の要因を最小限に抑えることです。

ここにも見られるように-http://jsperf.com/jquery-element-in-dom/28-コードは次のようになります:

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

これは、意味的にjQuery.contains(document.documentElement、elt [0])と同等です。


3

おそらく最もパフォーマンスの高い方法は次のとおりです。

document.contains(node); // boolean

これはjQueryでも機能します。

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

MDNからのソース

注意:


誰かがこの答えをどのように見ていますか?すばらしい答え+1(私はエディションを感謝しました、ありがとう)
ギル

1

私はこのアプローチが好きでした。jQueryもDOM検索もありません。最初に最上位の親(祖先)を見つけます。次に、それがdocumentElementかどうかを確認します。

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

1

親を反復する代わりに、要素がdomからデタッチされるときにすべて0である境界矩形を取得できます

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

幅0と高さ0の要素が上端ゼロ、左端ゼロであるエッジケースを処理する場合は、document.bodyまで親を反復して再確認できます。


このコードスニペットは問題を解決する可能性がありますが、なぜまたはどのように質問に答えるかは説明していません。コードの説明を含めてください。これは、投稿の品質を向上させるのに役立ちます。あなたは将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。 報告者/レビュアー: このようなコードのみの回答の場合は、投票しないでください。削除しないでください。
Luca Kiebel、

これも隠された要素を「DOMにない」ものとして認識しませんか?たとえば、display: noneboundingRectのない要素
Philipp

0

ペロのコメントに同意する。次のように行うこともできます:

$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

なぜだけではないの if( $('#foo').length === 0)...ですか?


@stevematdavies問題は、「指定されたjQueryオブジェクトの要素がDOMにあるかどうかをテストする方法」であり、「指定されたセレクター文字列に一致する要素がDOMにあるかどうかをテストする方法」ではありません。
Trevor Burnham

@TrevorBurnham:公平に言えば、作成に使用されたセレクターを使用し$fooて再クエリを実行し、再クエリが要素と一致するかどうかを確認することは、多くのシナリオで問題の実行可能な解決策のようです。jQueryとブラウザーの両方が特定のセレクター(IDなど)を最適化する方法が原因で、他のソリューションより高速になる場合があります。
Matt

@Matt $ fooは、DOMから切り離されたメモリ内の要素である可能性があり、DOMで一致するセレクターを持つ要素が存在する可能性があります。この質問への回答を探している人は、おそらくそれがDOMにあるかどうかを確認したいと思うでしょう。そのようなことをしている人は明らかにDOMをクエリする方法を知っています。
TJ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.