Я хотел бы смочь определить, был ли данный узел 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 свойство узла.
Я нашел ответ на свой собственный вопрос. Извините! Похоже, в последнее время я часто так делаю.
Фрагменты документа имеют nodeType 11, и никогда не вставляются в документ, поэтому вы можете проверить это следующим образом:
if (!node.parentNode || node.parentNode.nodeType == 11) {
// this node is floating free
}
Фрагмент документа нужен только тогда, когда вы вставляете более одного узла peer. Однако IE неявно создает его для всех вновь создаваемых узлов. В любом случае проверка nodeType для 11 работает.
Уровень 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)
Я думаю, что даже без недостатков 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.