Извлечение документов :
Описание: выбирает элементы, которые содержат хотя бы один элемент, соответствующий указанному селектору.
Выражение $( "div:has(p)" )
соответствует a, если <p>
существует где-либо среди его потомков, а не просто как прямой потомок.
Итак, :contains("keyword"):not(:has(:contains("keyword")))
выберет элемент, который содержит keyword
, но не имеет потомков , которые содержат keyword
.Другими словами, keyword
должен быть в родителе, но не в любом из потомков родителя.Например:
const match = $(`div:contains("keyword"):not(:has(:contains("keyword")))`);
console.log(match.length);
console.log(match[0]);
console.log(match[1]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="1" class="outer">
keyword
<div id="2" class="inner">
</div>
</div>
<div id="3" class="outer">
<div id="4" class="inner">
keyword
</div>
</div>
Он выбирает первый .outer
, поскольку .outer
имеет непосредственный текстовый узел потомок с keyword
.Он выбирает второй .inner
, поскольку он также имеет непосредственный текстовый узел потомок с keyword
.
Для селектора требуется, чтобы keyword
находился в текстовом узле, который является дочернимвыбран родительский элемент.
Вы можете эмулировать селектор с помощью ванильных методов DOM, например:
const match = [...document.querySelectorAll('div')]
.filter(
elm => [...elm.childNodes]
.filter(({ nodeType }) => nodeType === 3) // Only look through text nodes
.some(({ textContent }) => textContent.includes('keyword'))
);
console.log(match.length);
console.log(match[0]);
console.log(match[1]);
<div id="1" class="outer">
keyword
<div id="2" class="inner">
</div>
</div>
<div id="3" class="outer">
<div id="4" class="inner">
keyword
</div>
</div>