Как я могу найти предка элемента, который находится ближе всего к дереву, имеющему определенный класс, в чистом JavaScript ? Например, в дереве так:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
Тогда я хочу, div.near.ancestor
если я попробую это на p
и искать ancestor
.
javascript
html
dom
rvighne
источник
источник
p
элементу. Если вы действительно хотите получить родительский узел, вы можете это сделатьele.parentNode
.Ответы:
Обновление: теперь поддерживается в большинстве основных браузеров
Обратите внимание, что это может соответствовать селекторам, а не только классам
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
Для устаревших браузеров, которые не поддерживают,
closest()
но имеютmatches()
один, можно создать сопоставление селекторов, подобное сопоставлению классов @ rvighne:источник
closest
множеством дополнительных функций обхода DOM. Вы можете использовать эту реализацию самостоятельно или включить весь пакет, чтобы получить много новых функций в вашем коде.Это делает трюк:
Цикл while ждет, пока
el
не получит желаемый класс, и он устанавливаетel
в качествеel
родителя каждую итерацию, так что в итоге у вас есть предок с этим классом илиnull
.Вот скрипка , если кто-то хочет ее улучшить. Это не будет работать на старых браузерах (т.е. IE); см. эту таблицу совместимости для classList .
parentElement
используется здесь, потомуparentNode
что потребуется больше работы, чтобы убедиться, что узел является элементом.источник
.classList
см. Stackoverflow.com/q/5898656/218196 .parentElement
это довольно новое свойство (уровень DOM 4) иparentNode
существует с ... навсегда. ТакparentNode
же работает в старых браузерах, аparentElement
может и нет. Конечно, вы могли бы сделать тот же аргумент за / противclassList
, но у него нет простой альтернативы, какparentElement
имеет. Я на самом деле удивляюсь, почемуparentElement
вообще существует, кажется, это не добавляет никакой ценностиparentNode
.while (!el.classList.contains(cls) && (el = el.parentElement));
Используйте element.closest ()
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
Смотрите этот пример DOM:
Вот как бы вы использовали element.closest:
источник
На основе ответа 8472 и https://developer.mozilla.org/en-US/docs/Web/API/Element/matches вот кроссплатформенное решение 2017 года:
источник
@rvighne решение работает хорошо, но , как указано в комментариях ,
ParentElement
иClassList
оба имеют проблемы совместимости. Чтобы сделать его более совместимым, я использовал:parentNode
собственность вместоparentElement
собственностиindexOf
метод вclassName
свойстве вместоcontains
метода вclassList
свойстве.Конечно, indexOf просто ищет наличие этой строки, ему все равно, вся эта строка или нет. Поэтому, если у вас есть другой элемент с классом 'ancestor-type', он все равно вернется, если нашел 'ancestor', если это проблема для вас, возможно, вы можете использовать regexp, чтобы найти точное совпадение.
источник