代码之家  ›  专栏  ›  技术社区  ›  thomasrutter

javascript:如何判断节点对象是否已插入文档/其他元素中

  •  12
  • thomasrutter  · 技术社区  · 16 年前

    我想知道一个给定的dom节点是否已经被附加/插入到另一个节点中了,或者它是否刚刚从document.createElement()或类似的文件中出现,并且没有被放在任何地方。

    在大多数浏览器中,只需检查parentnode即可工作。

    if (!node.parentNode) {
      // this node is not part of a larger document
    }
    

    但是,在Internet Explorer中,新元素(即使在使用document.createElement()创建之后)似乎已经具有parentNode对象(属于disphtmldocument类型)??)

    还有其他不错的跨浏览器和可靠的方法吗?

    编辑 :似乎Internet Explorer正在隐式创建一个documentFragment(nodeType为11),并将其设置为节点的parentNode属性。

    4 回复  |  直到 13 年前
        1
  •  6
  •   nickf    16 年前

    我认为,即使没有IE的缺点,检查父节点的存在也不够。例如:

    var d = document.createElement('div');
    var s = document.createElement('span');
    d.appendChild(s);
    if (s.parentNode) {
        // this will run though it's not in the document
    }
    

    如果文档中有什么东西,那么最终它的祖先之一就是文档本身。试试这个,看看会怎么样:

    function inDocument(node) {
        var curr = node;
        while (curr != null) {
            curr = curr.parentNode;
            if (curr == document) return true;
        }
        return false;
    }
    
    // usage: 
    // if (inDocument(myNode)) { .. }
    

    如果您只想检查到某个深度,也就是说,您知道新创建的元素不会嵌套在IE片段之外,请尝试以下操作:

    function inDocument(node, depth) {
        depth = depth || 1000;
        var curr = node;
        while ((curr != document) && --depth) {
            curr = curr.parentNode;
            if (curr == null) return false;
        }
        return true;
    }
    
    inDocument(myNode, 2);  // check only up to two deep.
    inDocument(myNode);     // check up to 1000 deep.
    
        2
  •  5
  •   thomasrutter    16 年前

    我找到了自己问题的答案。对不起的!我最近好像经常这样做。

    文档片段的节点类型为11,并且从未插入到文档中,因此您可以这样检查它:

    if (!node.parentNode || node.parentNode.nodeType == 11) {
      // this node is floating free
    }
    

    当插入多个对等节点时,只需要一个文档片段。但是,IE隐式地为所有新创建的节点创建了一个。不管怎样,检查11个工作的节点类型。

        3
  •  2
  •   Rob W jminkler    13 年前

    DOM级别3引入了 compareDocumentPosition 方法 Node 它提供了关于两个节点如何相互关联的位置信息。其中一个返回值是 DOCUMENT_POSITION_DISCONNECTED 这意味着节点之间没有连接。无法使用此事实检查节点是否不包含在另一个节点中,方法是:

    Boolean(parent.compareDocumentPosition(descendant) & 16)
    
    DOCUMENT_POSITION_DISCONNECTED = 0x01;
    DOCUMENT_POSITION_PRECEDING    = 0x02;
    DOCUMENT_POSITION_FOLLOWING    = 0x04;
    DOCUMENT_POSITION_CONTAINS     = 0x08;
    DOCUMENT_POSITION_CONTAINED_BY = 0x10;
    DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
    

    谷歌已经写了一个跨浏览器的实现(我认为,没有提到IE那里)的 contains 可以在中找到的函数 http://code.google.com/p/doctype-mirror/wiki/ArticleNodeContains . 您可以使用它来检查给定节点是否是文档的子代

    .contains(document, someNode)
    
        4
  •  0
  •   user1170379    15 年前

    你在什么版本的IE中测试这个:

    
    if (!node.parentNode) {
      // this node is not part of a larger document
    }
    

    也许对于旧版本的IE,您应该尝试:

    
    if (!node.parentElement) {
      // this node is not part of a larger document
    }
    

    相反。

    尽管在九个选项中,您将得到>>空值<<,这两种方法都提供了顶部创建的容器元素尚未被解析,而这反过来又被转换为>>错误<<,完全符合您的需要。