【问题标题】:HTML element is attached to a documentHTML 元素附加到文档
【发布时间】:2018-09-20 02:33:35
【问题描述】:

当使用 removeChild() 从 DOM 中删除一个元素时,对该元素的引用仍然存在,但该元素不再存在于 DOM 中。
如何知道 HTML 元素(或其父元素)是否仍附加到文档?

【问题讨论】:

    标签: javascript html dom


    【解决方案1】:

    Node.prototype.contains() 是答案:

    if(document.body.contains(yourElement)) {
        // Yep, it's attached.
    }
    

    兼容性:IE5+

    【讨论】:

    • document.contains 不适用于 ie11,但 document.body.contains 可以。
    【解决方案2】:

    对于较新的浏览器(不支持 IE),您可以使用 Node.isConnected,它是 Node 上的一个属性并返回一个布尔值。

    Mozilla Node.isConnected

    document.querySelectorAll('#myElement').isConnected;
    

    【讨论】:

      【解决方案3】:

      继续检查元素的 parentNode,直到找到文档或用完节点。

      function is_element_in_document ( element ) {
          if (element === document) {
              return true;
          }
          element = element.parentNode;
          if (element) {
              return is_element_in_document ( element );
          }
          return false;
      }
      

      【讨论】:

      • 请不要使用递归!递归不一定是邪恶的,但会极大地损害性能!如果树中有 90 个节点,那么内存中将需要 90 个element 变量(每个级别一个)来执行此递归。此外,如果您的节点深度超过几百个,那么您可能会遇到 stackoverflow。此外,这个stackoverflow完全依赖于浏览器,所以有些浏览器会正确加载页面,而有些浏览器会出错。
      【解决方案4】:

      检查其parentNode 属性是否直接附加到文档。如果没有这样的父元素,则为null,否则为对父元素的引用。

      下一个代码说明了它的用法,它打印出null[Object HTMLBodyElement]null

      var elm = document.createElement("p");
      alert(elm.parentNode);
      
      document.body.appendChild(elm);
      alert(elm.parentNode);
      
      elm.parentNode.removeChild(elm);
      alert(elm.parentNode);
      

      再次注意,这仅适用于已使用 removeChild 删除的元素,如果删除了父元素,则必须检查该父元素的 parentNode 属性。

      要确定一个元素是否真的是文档的一部分,您必须检查最上面的父元素是否为document

      function element_is_part_of_document(element) {
          /* as long as the element is not document, and there is a parent element */
          while (element != document && element.parentNode) {
              /* jump to the parent element */
              element = element.parentNode;
          }
          /* at this stage, the parent is found. If null, the uppermost parent element */
          /* is not document, and therefore the element is not part of the document */
          return element == document;
      }
      

      【讨论】:

      • 这会告诉你一个元素是否附加到另一个元素,而不是文档。
      • @David:是的,但在答案的上下文中,这看起来不是问题。我一直在改进答案;)
      • Quentin,问题是“一个节点或其父母”,所以 Lekensteyn 的回答是正确的
      【解决方案5】:

      来自http://code.google.com/p/doctype-mirror/wiki/ArticleNodeContains

      <!DOCTYPE html>
      <html>
          <head>
              <meta charset="utf-8">
              <title></title>
              <script>
                  function contains(parent, descendant) {
                      return parent == descendant || Boolean(parent.compareDocumentPosition(descendant) & 16);
                  }
                  window.addEventListener("DOMContentLoaded", function() {
                      var p = document.getElementById("test");
                      //document.body.removeChild(p);
                      alert(contains(document, p));
                  }, false);
              </script>
          </head>
          <body>
              <p id="test">test</p>
          </body>
      </html>
      

      我只在 Opera 中测试过。

      该页面上也有其他选择。

      【讨论】:

      • @0x89 找到备用地址并修复链接。感谢您的报告。
      • 对于任何对 16 代表什么感到好奇的人,它是一个常量变量 Node.DOCUMENT_POSITION_CONTAINED_BY,如 developer.mozilla.org/en-US/docs/Web/API/Node/… 所述。 IE 8 及更低版本也不支持此方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多