我想选择包含文本的元素,无论其类型如何。我不想选择他们的后代。我尝试了这个$(":contains('Twilight')").css('border-left', '1px solid purple');
但是选择了带有和文本的元素,它是dom树中的祖先元素。
以下是一些HTML示例。我想选择标有<!-- THIS -->
的那些,没有别的。我该怎么做?
<div> <!-- no -->
<h1>Magical ponies</h1> <!-- no -->
<ul> <!-- no -->
<li>Fluttershy</li> <!-- no -->
<li>Pinkie pie</li> <!-- no -->
<li>Twilight sparkle</li> <!-- THIS -->
<li>Hurdurrdurr</li> <!-- no -->
</ul>
</div>
<div>Twilight is a movie too</div> <!-- THIS -->
<p>Hurr <!-- no -->
<span>Twilight ZONE</span> <!-- THIS -->
Durr</p>
这是一个可以使用的jsfiddle:http://jsfiddle.net/34C7Z/ - 我特别希望解决方案是jquery而不是本机JS。
答案 0 :(得分:1)
我看到的唯一解决方案:
$("*").filter(function(){
return $(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.text() //get the text
.indexOf("Twilight") >= 0;
}).css('border-left', '1px solid purple');
我从这里开始使用过滤器功能体:Using .text() to retrieve only text not nested in child tags
问题是contains
选择器使用text
jQuery函数返回获取元素后面的所有内容并剥离html标记。这就是为什么你必须以编程方式执行它,jQuery没有函数或选择器只返回嵌套子节点中的文本。
您应该在开头更改$("*")
选择器。
答案 1 :(得分:0)
检查它(在this SO answer的帮助下):
$('*').contents().filter(function(){
return this.data && this.data.match(/Twilight/g);
}).parent().css('border-left','1px solid purple');
我在HTML的一个稍微不同的版本上测试了它,其中包含另一个用例:它不是假设文本是后代列表中的最后一个节点,而是考虑在文本/ CDATA旁边存在兄弟节点。
哦,作为奖励,你得到正则表达式,并且不必通过复制节点来消耗更多内存 - 这只是遍历。
更新的小提琴:http://jsfiddle.net/34C7Z/23/
关于下面的“双重应用/检查”的评论 - 在这种情况下,如果匹配的元素包含另一个匹配的元素,两者都将应用css - 这将确保只有相对的最顶层匹配(可以使用一些清理):
var v = $('*').contents().filter(function(){
return this.data && this.data.match(/Twilight/g);
}).parent();
v.children().each(function(){
v = v.has(this)?v.not(this):v; // meh, modifies the original, w/e
});
v.css('border-left', '1px solid purple');
这个版本的解决方案的小提琴:http://jsfiddle.net/34C7Z/26/
答案 2 :(得分:-2)
嗯,这就是我放弃之前所做的一切。不知道为什么,但jQuery只是不关心.not
选择器是否存在或者是否存在。
var e = $(document);
e.find("*").css('border-left', '1px solid purple');
var val = e.not(':contains("Twilight")');
val.css('border-left', '7px solid red');
这是fiddle。