如何使用jQuery通过文本内容查找元素?

406

有人能告诉我是否可以根据元素的内容而不是根据ID来查找元素吗?

我试图查找没有独特类或ID的元素。(然后我需要找到该元素的父元素。)


1
http://api.jquery.com/category/selectors/ - Felix Kling
1
可能是重复的问题:如何使用jQuery选择包含特定文本值的span? - AncientSwordRage
8个回答

570
您可以使用 :contains 选择器根据元素的内容来获取元素。

这里有演示链接

$('div:contains("test")').css('background-color', 'red');
<div>This is a test</div>
<div>Another Div</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>


5
好的,但它是区分大小写的。我们有办法进行不区分大小写的搜索吗? - Dipu Raj
142
дҪ йңҖиҰҒдҪҝз”Ё.filterд»ЈжӣҝгҖӮ $('div').filter(function(){ return $(this).text().toLowerCase() === 'test';}) зҡ„ж„ҸжҖқжҳҜйҖүеҸ–жүҖжңүdivе…ғзҙ дёӯж–Үжң¬еҶ…е®№дёәвҖңtestвҖқзҡ„е…ғзҙ гҖӮ - gen_Eric
6
请采用@RocketHazmat所使用的方法,假设您有5个元素,它们都以“Register Contract”为前缀,并且每个元素都有一个数字后缀。您最终会选择所有这些元素,而实际上您只想要文本为“Register Contract 26”的元素。 - Riveascore
2
如果有人喜欢在括号中使用空格,以下代码将无法正常工作:$('div:contains( "test" )').css('background-color', 'red'); - M Katz
2
如果您在整个页面上运行它,则此方法无法正常工作,因为所有 div 元素都将包含所需文本。强烈建议检查是否没有其他子元素。 - Maxime Culea
显示剩余4条评论

108

在jQuery文档中,它说:

匹配的文本可以直接出现在所选元素内,在该元素的任何后代中,或者两者结合

因此,仅使用:contains()选择器是不够的,您还需要检查您搜索的文本是否是要定位的元素的直接内容,就像这样:

function findElementByText(text) {
    var jSpot = $("b:contains(" + text + ")")
                .filter(function() { return $(this).children().length === 0;})
                .parent();  // because you asked the parent of that element

    return jSpot;
}

3
在以下场景中,此解决方案可能会失败:<li>Hello <a href='#'>World</a>, How Are You. 。如果搜索的是“ How”,则条件将失败。 - me_digvijay

30

伙计们,我知道这已经是老问题了,但是我有一个解决方案,我认为比所有其他解决方案都要好。首先,它克服了jquery :contains()方法所带来的大小写敏感性问题:

var text = "text";

var search = $( "ul li label" ).filter( function ()
{
    return $( this ).text().toLowerCase().indexOf( text.toLowerCase() ) >= 0;
}).first(); // Returns the first element that matches the text. You can return the last one with .last()

希望将来有人发现它有用。


25

Rocket的答案不起作用。

<div>hhhhhh
<div>This is a test</div>
<div>Another Div</div>
</div>

我只是修改了他这里的演示,你可以看到选择了根DOM。

$('div:contains("test"):last').css('background-color', 'red');

在代码中添加":last"选择器以解决此问题。


1
当选择器返回多个结果并且您需要将其缩小到特定元素时,此方法效果最佳,而您没有“Id”属性可供参考。 - Trevor

21
以下jQuery选择包含文本但没有子元素的div节点,即DOM树的叶节点。

$('div:contains("test"):not(:has(*))').css('background-color', 'red');
<div>div1
<div>This is a test, nested in div1</div>
<div>Nested in div1<div>
</div>
<div>div2 test
<div>This is another test, nested in div2</div>
<div>Nested in div2</div>
</div>
<div>
div3
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>


5
这是最佳答案! - Calciol
请注意,这是因为jQuery中提供了:contains选择器,该选择器不是CSS标准的一部分。Microsoft似乎在其Web引擎的先前版本中支持了这样的选择器。 - Aurovrata

17

我认为这是最好的方法。

$.fn.findByContentText = function (text) {
    return $(this).contents().filter(function () {
        return $(this).text().trim() == text.trim();
    });
};

9

是的,使用jQuery中的contains选择器。


14
不,不要这样说:“contains:”并不是进行精确匹配,只是检查“针”是否包含在“干草堆”中(因此得名)。正如其他人在这里所说的那样。 - mike rodent
5
这不是一个答案。 - lharby

2
到目前为止,所有的答案都无法匹配包含特定文本的直接子文本节点的所有特定元素。考虑以下示例。我们想找到所有霍比特人,也就是包含直接子文本节点、包含单词"hobbit"(包括边界,忽略大小写)的所有
元素。

$(function() {
    
    const ELEMTYPE = Node.ELEMENT_NODE
    const TEXTTYPE = Node.TEXT_NODE
    
    /*
    Behaves a bit like Python's os.walk().
    The `topdown` parameter is not strictly necessary for this example.
    */
    function* walk_text(root, topdown=true) {
        const childs = []
        const textchilds = []
        for (const child of root.childNodes) {
            const childtype = child.nodeType
            if (childtype === ELEMTYPE) {
                childs.push(child)
            } else if (childtype === TEXTTYPE) {
                textchilds.push(child)
            }
        }
        if (topdown) {
            yield [root, textchilds]
        }
        for (const child of childs) {
            yield* walk_text(child, topdown)
        }
        if (!topdown) {
            yield [root, textchilds]
        }
    }
    
    function* walk_matching(startnode, nodepat, textpat) {
        for ( [elem, textchilds] of walk_text(startnode) ) {
            if ( nodepat.test(elem.nodeName) ) {
                for ( const textchild of textchilds ) {
                    if ( textpat.test(textchild.nodeValue) ) {
                        yield elem
                        break
                    }
                }
            }
        }
    }
    
    // raw dom node
    let startnode = $('body')[0]
    
    // search for element nodes with names matching this pattern ...
    let nodepat = /^div$/i
    
    // ... containing direct child text nodes matching this pattern
    let textpat = /\bhobbit\b/i
    
    for ( const node of walk_matching( startnode, nodepat, textpat ) ) {
        $(node).css({
            border: '1px solid black',
            color: 'black'
        })
    }

});
div {
    margin:10px 0;
    padding: 10px;
    border: 1px solid silver;
    color: silver;
    font-style:italic;
}

div:before {
    display:block;
    content: attr(name);
    font-style:normal;
}

/* Inserted by SO, we are not interested in it */
body + div {
    display: none;
}
<!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Find the hobbits</title>
    </head>
    <body>
        <div name='Tolkien'>
            book writer
            <div name='Elrond'>
                elven king
                <div name='Arwen'>elven princess</div>
                <div name='Aragorn'>human king, son-in-law</div>
            </div>
            <div name='Gandalf'>
                wizard, expert for hobbits
                <div name='Bilbo'>
                    old hobbit
                    <div name='Frodo'>
                        young hobbit
                        <div name='Samweis'>best friend hobbit</div>
                    </div>
                </div>
                <div name='Gollum'>ex hobbit</div>
                <div name='Odo'>hobbit</div>
            </div>
        </div>
        <script src= "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    </body>
</html>

其他答案(搜索“霍比特”时)如下:

  • Rocket Hazmat的答案:托尔金、甘道夫、比尔博、弗罗多、山姆威斯、戈卢姆、奥多
  • Morgs的答案:托尔金
  • yoav barnea的答案:甘道夫、弗罗多
  • Nicholas Sushkin的答案:山姆威斯、戈卢姆、奥多
  • Rocket Hazmat在评论中提供的答案、Terry Lin的答案、rplaurindo的答案:奥多

所有这些答案都有道理,具体取决于您想要做什么。选择明智,因为Rocket Hazmat的答案、Morgs的答案和Terry Lin的答案比我的解决方案快两倍以上。我猜这是因为它们不需要遍历整个DOM。大多数使用.filter()的答案执行非常快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接