【问题标题】:How to check an element retrieved from DOM is still present in DOM如何检查从 DOM 中检索到的元素是否仍然存在于 DOM 中
【发布时间】:2012-09-28 22:44:59
【问题描述】:

假设我有一个 DOM 元素,作为事件的参数,例如 click。

$(document).click(function() {
    myElement = $(this);
});

我以后如何检查 myElement 是否仍在 DOM 中? 我不能使用 .length 或任何其他类似的东西,因为它现在仍然引用保存的元素和 DOM 的状态,对吧?

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    您可以检查元素父级:

    function isInDom(obj) {
        var root = obj.parents('html')[0] 
        return !!(root && root === document.documentElement);
    }
    
    
    if(isInDom(myElement)) {
         ...
    }
    

    这是工作小提琴:http://jsfiddle.net/vnxhQ/7/

    【讨论】:

    • 这个测试元素在存储时是否有父元素,与元素是否还在DOM中无关。
    • myElement 需要是一个包装元素的 jQuery 对象,但是.. 但是,我不相信这与存储时有任何关系。
    • 啊...但是 DOM 对象是什么时候用 jQuery 包装的...?
    • @Inferpse 你是对的,我在fiddle 中测试了它,+1
    • 一个元素可能有一个父 body-element 而不是文档的一部分:jsfiddle.net/doktormolle/vnxhQ/1
    【解决方案2】:

    为了测试DOM中是否还存在一个元素,需要再次爬取DOM:

    // store it in some shared scope
    var myElement;
    $(document).click(function() {
        myElement = $(this);
    });
    
    // sometime later...
    if ($('#' + myElement.attr('id')).length > 0) {
        // it still exists
    } else {
        // it no longer exists
    }
    

    不过,您点击的元素都必须有 ids 才能正常工作。可以使用类或任何其他选择器。

    编辑:请参阅this question,了解如何为任何给定的 DOM 元素获取唯一选择器。

    【讨论】:

      【解决方案3】:

      这是假设您设置了可能的“可点击”元素的 id

      var idRef;
      $(document).on('click', function() {
          idRef = this.id;    
      });
      

      稍后..

      var exists = document.getElementById(idRef).length > 0;
      

      【讨论】:

        【解决方案4】:

        您可以使用 jQuery 对象的未记录的.selector 属性来查看元素是否仍在 DOM 中,前提是它使用唯一 ID。​很明显

        http://jsfiddle.net/mblase75/CC2Vn/

        $two = $('#two');
        console.log($($two.selector).length); // 1
        $two.remove();
        console.log($($two.selector).length); // 0
        

        有关如何获取 jQuery 对象的选择器的更多信息,请参阅this question,该选择器可能会或可能不会唯一地描述它包含的 DOM 元素。

        【讨论】:

          【解决方案5】:

          到目前为止,我看到的唯一可靠的方法是检查元素是否在 document.getElementsByTagName('*')

          function isInDoc(element)
          {
            var elements=document.getElementsByTagName(element.tagName);
            for(var i=0;i<elements.length;++i)
            {
              if(elements[i]===element)return true;
            }
            return false;
          }
          

          演示:http://jsfiddle.net/doktormolle/hX8eN/


          &lt;edit&gt;

          Node.contains() 似乎所有主流浏览器都支持,所以我最后建议:

          if(document.documentElement.contains(myElement))
          

          演示:http://jsfiddle.net/doktormolle/LZUx3/

          【讨论】:

          • 呃……真的吗?那是很多标签。也许您可以将 Inferpse 的答案与您的答案结合起来 1. 测试以查看元素是否来自 body 标签。 2. 测试那个元素的body标签是否是文档的body标签。
          • (或者文档可以有多个body标签??)
          • 查看我的回答以澄清我的意思。
          • 我明白你的意思。但我无法想象没有原生且简单的方法。 Node.contains() 对我来说很好。
          • 不错!但是 Firefox 9+ 支持这种方法?
          【解决方案6】:

          只是为了添加一些东西:

          这确实是 Inferpse 的回答,针对 Dr.Molle 的极端案例进行了微调,即创建另一个 body 元素,该元素可能包含从一般 DOM 树中删除的元素(或者,当然,也许该元素一开始就从未在 DOM 中.) 就像 Inferspe 的回答一样,它需要一个 jQuery 包装的对象,而不是元素本身。

          function isInDom(jqobj) {
              var someBody = jqobj.parents('body');
              return someBody.length > 0 && someBody.get(0) === document.body;
          }
          ​
          

          我必须承认我无法弄清楚如何尝试打破它。

          编辑:哦,是的... jsFiddle:http://jsfiddle.net/vnxhQ/5/

          编辑二:当然,如果我们不是在谈论链接或脚本元素(任何可能进入head,而不是body,我想这可能会很好:-/

          【讨论】:

            【解决方案7】:

            也许实现 Inferpse 功能的更好方法是扩展 jQuery:

            jQuery.fn.extend({
                isInDom: function() {
                    var root = this.eq(0).parents('html')[0];
                    return !!(root && root === document.documentElement);
                }
            })
            

            用法:

            $("div").isInDom() //returns true if your dom contains a div
            $("<div />").isInDom() //returns false
            $().isInDom() //returns false
            

            【讨论】:

              【解决方案8】:

              您可能正在寻找Node.isConnected

              【讨论】:

                猜你喜欢
                • 2015-10-02
                • 2014-11-14
                • 2011-03-25
                • 2022-06-21
                • 2014-09-30
                • 2013-11-09
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多