我试图了解以下jquery代码将返回什么?
$(`:contains("keyword"):not(:has(:contains("keyword")))`)
答案 0 :(得分:2)
签出docs:
说明:选择包含至少一个与指定选择器匹配的元素的元素。
如果
$( "div:has(p)" )
的后代中存在任何地方,而不仅仅是直接子代,则表达式<p>
与a匹配。
因此,: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
,是因为它还有一个直接的 text节点后代和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>