Jquery 按内部文本筛选()返回空的父节点
我需要找到页面上与某些内部文本匹配的所有元素:Jquery 按内部文本筛选()返回空的父节点,jquery,Jquery,我需要找到页面上与某些内部文本匹配的所有元素: $("body *:visible").filter( function(){ return $(this).text() == 'jQuery' } ); 但是,在某些情况下,我会得到包含匹配元素的父节点。 例如。 第一场比赛: 第二场比赛: 如何从选择中删除所有具有父节点的元素,而只保留真正包含已定义内部文本的元素? 对于测试,您可以尝试在上执行上面的脚本。此代码将仅迭代该元素的文本节点,然后进行比较 $("body *:visibl
$("body *:visible").filter( function(){ return $(this).text() == 'jQuery' } );
但是,在某些情况下,我会得到包含匹配元素的父节点。
例如。
第一场比赛:
第二场比赛:
如何从选择中删除所有具有父节点的元素,而只保留真正包含已定义内部文本的元素?
对于测试,您可以尝试在上执行上面的脚本。此代码将仅迭代该元素的文本节点,然后进行比较
$("body *:visible").filter(function() {
var childNodes = this.childNodes,
text = '';
$.each(childNodes, function(i, node) {
if (node.nodeType != 3) {
return true;
}
text += node.data;
});
return text == 'jQuery';
});
此外,如果要执行不区分大小写的搜索,请确保在比较要匹配的字符串的小写版本之前,在文本节点上使用
toLowerCase()
。您的逻辑失败,因为您正在比较.text()
值。这将去除所有HTML标记,包括子节点的标记。如果希望元素不包含子元素且与该文本匹配,只需修改为:
$("body *:visible").filter( function(){ return $(this).html().toLowerCase() == 'jquery' });
话虽如此,这是一个非常糟糕的过滤器,我怀疑它相当慢。这是因为返回元素的内部文本,其中包括其所有子元素的内部文本
为了仅匹配直接子元素和文本节点,必须使用:
$("body *:visible").filter(function() {
var textNodes = $(this).contents().filter(function() {
return this.nodeType == 3;
});
return (textNodes.length > 0 && textNodes[0].nodeValue == "jQuery");
});
与其出于未知原因链接到jQuery页面,不如在jsfiddle.net上创建一个测试来演示您的问题。此外,由于比较区分大小写,因此示例案例可能不准确。我相信这种逻辑在以下情况下会失败:
jQueryMore content
,因为您只比较第一个子节点类型。OP似乎只想返回只包含单词“jQuery”而不包含其他内容的节点。这只是我的猜测@阿达姆特尔森:听起来你在看我的代码的早期版本:)我确实是。编辑得好。然而,当节点类型不是text类型时,您不应该只返回false而不是true吗?@AdamTerlson:the返回true
只是为了让each()
跳过该迭代。是的,但是一旦您遇到非text节点的内容,您就已经知道您的元素包含的不仅仅是textNode,因此,您也可以通过返回false和filter函数的进一步返回false来打破循环。这看起来不错,但是,它不会只与第一个文本节点进行比较吗?@alex,事实上,它只检查第一个文本节点。这是因为提问者只想匹配其完整内部文本等于jQuery
的元素。在这种情况下,将不存在空白文本节点,并且该值将存储在单个文本节点中。Frédéric,谢谢。您的解决方案非常有效,但找到元素大约需要1-2秒。是否有机会提高这种方法的性能(我需要它包含在我的Selenium 2(WebDriver)项目中,测试的性能对我来说非常重要)?谢谢大家。这个问题可以结束了。