Проверка вложенности DOM элементов в JS: кроссбраузерное решение
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
// Проверка на вложенность с помощью .contains()
var isContained = document.getElementById('parent').contains(document.getElementById('child'));
Значение переменной isContained
будет true, если элемент child
находится внутри элемента parent
непосредственно или косвенно. В противном случае вернётся false.
Менее очевидные ситуации
При отсутствии явной связи родитель-потомок между элементами можно воспользоваться спуском по DOM-дереву вверх:
// Поиск прародителя по дереву вверх до самого корня
function isDescendant(parent, child) {
var node = child.parentNode;
while (node) {
if (node === parent) {
return true; // найден искомый предок.
}
node = node.parentNode; // Продолжаем поиск.
}
return false; // предок не найден. 😔
}
Эта функция пригодится, когда child
может быть глубоко вложен в parent
.
Альтернативные методы проверки на вложенность
Поиск элементов можно осуществлять также с помощью метода querySelector
:
// Используем .querySelector()
var isContained = parent.querySelector('.child') !== null; // проверяем, присутствует ли элемент с классом '.child' внутри 'parent'?
Этот код вернёт true, если в parent
на любом уровне вложенности найден элемент с классом .child
.
Более глубокое изучение
Изучение связей между узлами можно осуществлять с использованием compareDocumentPosition
:
// Анализ положения узлов
var position = parent.compareDocumentPosition(child);
var isContained = !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY); // Проверяем, содержится ли 'child' в 'parent'?
Значение isContained
будет true, если child
находится внутри parent
. Проверка этого осуществляется при помощи побитовых операций.
Визуализация
let birdNest = document.querySelector('#birdNest');
let bird = document.querySelector('#bird');
let isBirdInNest = birdNest.contains(bird);
В приведённом примере isBirdInNest
позволяет выяснить, находится ли птичка (🐣
) в своём гнезде (🌳
), аналогично тому, как мы наблюдаем за птицами в природе.
Учтите неоднородность поведения браузеров
Несмотря на широкую поддержку метода contains()
, важно помнить о его возможно разном поведении в разных браузерах. Использование полифиллов может устранить эти различия.
Заботьтесь о производительности
Метод contains()
довольно быстр, но при необходимости выполнения множества проверок на большом DOM или при частых вызовах его, кэширование результатов может помочь оптимизировать производительность.
Профилактика ошибок
Важной является проверка входных данных на корректность, чтобы избежать ошибок типа TypeError: Cannot read property 'contains' of null
.
Индивидуальные подходы
Учитывайте уникальность каждого проекта. В зависимости от задачи, можно изящно сочетать использование contains()
с другими методами запроса и логическими операциями.