JavaScript: как сказать, был ли объект узла вставлен в элемент документа/другого уже

Я хотел бы смочь определить, был ли данный узел 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 (с типом узла 11) и устанавливает это как parentNode свойство узла.

12
задан thomasrutter 18 April 2010 в 06:41
поделиться

3 ответа

Я нашел ответ на свой собственный вопрос. Извините! Похоже, в последнее время я часто так делаю.

Фрагменты документа имеют nodeType 11, и никогда не вставляются в документ, поэтому вы можете проверить это следующим образом:

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

Фрагмент документа нужен только тогда, когда вы вставляете более одного узла peer. Однако IE неявно создает его для всех вновь создаваемых узлов. В любом случае проверка nodeType для 11 работает.

5
ответ дан 2 December 2019 в 21:23
поделиться

Уровень 3 модели DOM представил метод compareDocumentPosition для узла , который предоставляет позиционную информацию о том, как два узла связаны друг другу. Одно из возвращаемых значений - 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;

Google написал кроссбраузерную реализацию (я думаю, нет упоминания об IE) функции содержит , которая может можно найти по адресу http://code.google.com/p/doctype-mirror/wiki/ArticleNodeContains . Вы можете использовать это для проверки, является ли данный узел потомком документа

.contains(document, someNode)
2
ответ дан 2 December 2019 в 21:23
поделиться

Я думаю, что даже без недостатков IE проверки наличия parentNode может быть недостаточно. Например:

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.
6
ответ дан 2 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: