Я умею это делать:
<div id="myDiv">
<div class="foo"></div>
</div>
myDiv = getElementById("myDiv");
myDiv.querySelectorAll("#myDiv > .foo");
То есть я могу успешно получить всех прямых потомков myDiv
элемента, у которого есть класс .foo
.
Проблема в том, что меня беспокоит, что я должен включить #myDiv
в селектор, потому что я выполняю запрос к myDiv
элементу (поэтому он явно избыточен).
Я должен иметь возможность оставить #myDiv
выключенным, но тогда селектор не является допустимым синтаксисом, поскольку он начинается с >
.
Кто-нибудь знает, как написать селектор, который получает только прямых потомков элемента, на котором работает селектор?
javascript
dom
css-selectors
mattsh
источник
источник
Ответы:
Хороший вопрос. В то время, когда был задан вопрос, универсально реализованного способа выполнения «запросов с корневым комбинатором» (как их назвал Джон Ресиг ) не существовало.
Теперь был представлен псевдокласс : scope . Он не поддерживается в [pre-Chrominum] версиях Edge или IE, но уже несколько лет поддерживается Safari. Используя это, ваш код может стать:
Обратите внимание, что в некоторых случаях вы также можете пропустить
.querySelectorAll
и использовать другие старые добрые функции DOM API. Например, вместо того, чтобыmyDiv.querySelectorAll(":scope > *")
вы могли просто написатьmyDiv.children
, например.В противном случае, если вы еще не можете полагаться на него
:scope
, я не могу придумать другого способа справиться с вашей ситуацией без добавления дополнительной логики настраиваемого фильтра (например, найтиmyDiv.getElementsByClassName("foo")
чей.parentNode === myDiv
), и, очевидно, не идеален, если вы пытаетесь поддерживать один путь кода, который действительно просто хочет принять произвольную строку селектора в качестве ввода и список совпадений в качестве вывода! Но если вы, как и я, задали этот вопрос просто потому, что застряли, думая «все, что у вас было, это молоток», не забывайте, что DOM предлагает множество других инструментов.источник
myDiv.getElementsByClassName("foo")
это не то же самое, аmyDiv.querySelectorAll("> .foo")
больше похожеmyDiv.querySelectorAll(".foo")
(что, кстати, действительно работает) тем, что он находит всех потомков,.foo
а не только потомков.<style scoped>
) не имеют ничего общего с:scope
псевдоселектором, описанным в этом ответе.Правильный способ написать селектор, «привязанный» к текущему элементу, - это использовать
:scope
.Однако поддержка браузера ограничена, и вам понадобится прокладка, если вы хотите ее использовать. Для этого я построил scopedQuerySelectorShim .
источник
:scope
спецификация в настоящее время является «Рабочим проектом» и поэтому может быть изменена. Скорее всего, он все еще будет работать так, если / когда он будет принят, но немного рано говорить, что это «правильный способ», по моему мнению.Вот гибкий метод, написанный на ванильном JS, который позволяет вам запускать запрос селектора CSS только для прямых потомков элемента:
источник
Math.random().toString(36).substr(2, 10)
создания одного и того же токена более одного раза.any dupe would need to also be a child of the same parent node
,id
атрибуты охватывают весь документ. Вы правы, шансы по-прежнему весьма незначительны, но спасибо за то, что выбрали большую дорогу и добавили этот счетчик :)если вы точно знаете, что элемент уникален (например, в вашем случае с идентификатором):
Для более «глобального» решения: (используйте прокладку matchSelector )
где
elm
ваш родительский элемент иsel
ваш селектор. Можно полностью использовать как прототип.источник
matchesSelector
префикса (что даже не работает в последней версии Chrome), оно загрязняет глобальное пространство имен (ret не было объявлено), оно не возвращает NodeList, как ожидается, querySelectorMethods. Я не думаю, что это хорошее решение, поэтому и проголосовал против.Следующее решение отличается от предложенных до сих пор и работает для меня.
Причина в том, что вы сначала выбираете всех совпадающих потомков, а затем отфильтровываете те, которые не являются прямыми потомками. Потомок является прямым потомком, если у него нет подходящего родителя с таким же селектором.
НТН!
источник
Я создал функцию для этой ситуации, думал, что поделюсь ею.
По сути, то, что вы делаете, генерирует случайную строку (функция randomString здесь - импортированный модуль npm, но вы можете создать свой собственный.), А затем используя эту случайную строку, чтобы гарантировать, что вы получите элемент, который ожидаете в селекторе. Тогда вы можете использовать
>
после этого.Причина, по которой я не использую атрибут id, заключается в том, что атрибут id уже может использоваться, и я не хочу его отменять.
источник
Что ж, мы можем легко получить всех прямых потомков элемента, используя,
childNodes
и мы можем выбрать предков с определенным классомquerySelectorAll
, поэтому нетрудно представить, что мы могли бы создать новую функцию, которая получает оба и сравнивает их.Примечание. Это вернет массив узлов, а не список узлов.
использование
источник
Я хотел бы добавить, что вы можете расширить совместимость : scope , просто назначив временный атрибут текущему узлу.
источник
Я бы пошел с
источник
Я просто делаю это, даже не пробуя. Это сработает?
Попробуйте, может он сработает, а может и нет. Apolovies, но сейчас я не за компьютером, чтобы попробовать (отвечает с моего iPhone).
источник