Как я могу проверить, является ли один элемент DOM дочерним по отношению к другому элементу DOM? Есть ли встроенные методы для этого? Например, что-то вроде:
if (element1.hasDescendant(element2))
или
if (element2.hasParent(element1))
Если нет, то есть идеи, как это сделать? Это также должно быть кросс-браузер. Я должен также упомянуть, что ребенок может быть вложен на много уровней ниже родительского.
javascript
dom
AJ.
источник
источник
Ответы:
Обновление: теперь есть собственный способ добиться этого.
Node.contains()
, Упоминается в комментариях и ниже ответов.Старый ответ:
Использование
parentNode
свойства должно работать. Это также довольно безопасно с точки зрения кросс-браузера. Если известно, что отношения имеют глубину в один уровень, вы можете проверить это просто:Если дочерний элемент может быть вложен произвольно глубоко внутрь родительского элемента, вы можете использовать функцию, подобную следующей, для проверки взаимосвязи:
источник
Node.contains
(хотя нет страницы caniuse)Node.contains
? :)Вы должны использовать
Node.contains
, так как теперь это стандартно и доступно во всех браузерах.https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
источник
var parent = document.getElementById('menu'); var allElements = document.getElementsByTagName('a'); if (parent.contains(allElements[i]) { alert('Link is inside meni'); }
Я просто должен был поделиться «моим».
Хотя концептуально тот же ответ, что и у Асафа (благодаря той же кросс-браузерной совместимости, даже с IE6), он намного меньше и полезен, когда размер выше, и / или когда он не нужен так часто.
..или как однострочник ( всего 64 символа !)
и jsfiddle здесь .
Использование:
childOf(child, parent)
возвращает логическое значениеtrue
|false
,Объяснение:
while
оценивает, пока выполняется условие whiletrue
.Оператор
&&
(AND) возвращает это логическое значение true / false после оценки левой и правой частей, но только если левая часть была истинной (left-hand && right-hand
) .Левая сторона (из
&&
) имеет вид :(c=c.parentNode)
.Это первый будет назначить
parentNode
изc
к ,c
а затем оператор И будет оценивать полученныйc
как логическое значение.Поскольку
parentNode
возвращается,null
если родительского элемента не осталось, иnull
преобразуется вfalse
, цикл while будет корректно останавливаться, когда родительских элементов больше нет.Правая (из
&&
) имеет вид :c!==p
.Оператор
!==
сравнения « не совсем равен». Поэтому, если родитель ребенка не является родителем (вы указали), он оценивает егоtrue
, но если родитель ребенка является родителем, то он оценивает егоfalse
.Таким образом, если значение
c!==p
равно false,&&
оператор возвращаетсяfalse
как условие while, и цикл while останавливается. (Обратите внимание, что в теле while нет необходимости, и;
требуется точка с запятой.)Таким образом, когда цикл while завершается,
c
это либо узел (неnull
), когда он нашел родителя, ИЛИnull
(если цикл прошел до конца, не найдя соответствия).Таким образом , мы просто
return
тот факт (конвертируется в логическое значение, вместо узла) с:return !!c;
: от!
(NOT
оператор) инвертирует логическое значение (true
становитсяfalse
и наоборот).!c
преобразуетc
(узел или ноль) в логическое значение, прежде чем оно сможет инвертировать это значение. Таким образом, добавление second!
(!!c
) преобразует это ложное значение обратно в истинное (именно поэтому двойник!!
часто используется для «преобразования чего-либо в логическое значение»).Дополнительно:
тело / полезная нагрузка функции настолько малы, что в зависимости от случая (например, когда она используется не часто и появляется в коде только один раз), можно даже опустить функцию (обтекание) и просто использовать цикл while:
вместо того:
источник
!==
) может улучшить скорость, дав понять компилятору, что он может пропустить проверку типов и необязательные неявные шаги преобразования, которые могут произойти при сравнении с произвольным равенством, тем самым улучшая скорость (более точно описывая то, что мы хочу случиться, что тоже выгодно программисту). Я также, кажется, вспоминаю, когда я писал это, что только произвольное сравнение (!=
) было либо очень подвержено ошибкам, либо не работало вообще в некоторых старых браузерах (я подозреваю, что это было в IE6, но я забыл ).Другое решение, которое не было упомянуто:
Пример здесь
Неважно, является ли элемент прямым потомком, он будет работать на любой глубине.
В качестве альтернативы, используя
.contains()
метод :Пример здесь
источник
Посмотрите на Node # compareDocumentPosition .
Другие отношения включают в себя
DOCUMENT_POSITION_DISCONNECTED
,DOCUMENT_POSITION_PRECEDING
иDOCUMENT_POSITION_FOLLOWING
.Не поддерживается в IE <= 8.
источник
Вы можете использовать метод содержит
var result = parent.contains(child);
или вы можете попробовать использовать compareDocumentPosition ()
var result = nodeA.compareDocumentPosition(nodeB);
Последний более мощный: он возвращает битовую маску в качестве результата.
источник
Я наткнулся на замечательный кусок кода, чтобы проверить, является ли элемент дочерним по отношению к другому элементу. Я должен использовать это, потому что IE не поддерживает
.contains
метод элемента. Надеюсь, это поможет и другим.Ниже приведена функция:
источник
Попробуй это:
источник
Я недавно сталкивался с этой функцией, которая может делать:
Node.compareDocumentPosition ()
источник