如何直接定位具有文本的元素,而不是父母的元素?

时间:2013-11-19 15:03:49

标签: jquery html

我想选择包含文本的元素,无论其类型如何。我不想选择他们的后代。我尝试了这个$(":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。

3 个答案:

答案 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