【问题标题】:jQuery: find element by textjQuery:按文本查找元素
【发布时间】:2011-11-11 10:07:57
【问题描述】:

谁能告诉我是否可以根据元素的内容而不是 idclass 找到元素?

我正在尝试查找没有不同类或 ID 的元素。 (然后我需要找到该元素的父元素。)

【问题讨论】:

标签: jquery text find


【解决方案1】:

是的,使用 jQuery contains 选择器。

【讨论】:

  • er,不,不要:'contains:' 不做完全匹配,只有针是否包含在大海捞针中(因此命名)......正如其他人所说的那样
  • 这不是答案。
【解决方案2】:

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

Demo here

$('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>

【讨论】:

  • 很好,但它区分大小写。无论如何我们可以进行不区分大小写的搜索吗?
  • @DipuRaj:你必须改用.filter$('div').filter(function(){ return $(this).text().toLowerCase() === 'test';})
  • 是的,请使用 @RocketHazmat 使用的方法,假设您有 5 个元素,全部以“注册合同”为前缀,每个元素都有一个数字后缀.您最终会全选,而实际上您只想要带有文本的元素:'Register Contract 26'
  • 虽然 :contains 区分大小写,但它对我有用,因为我传递了要查找的确切文本字符串。
  • 如果它对喜欢在括号中使用空格的其他人有所帮助,以下方法不起作用$('div:contains( "test" )').css('background-color', 'red');
【解决方案3】:

在 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;
}

【讨论】:

  • 刚刚遇到了这个问题。这应该更高。
  • 此解决方案在以下情况下可能会失败:&lt;li&gt;Hello &lt;a href='#'&gt;World&lt;/a&gt;, How Are You. 。在这里,如果正在搜索How,我认为条件将失败。
【解决方案4】:

Rocket 的回答无效。

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

我只是修改了他的DEMO here,可以看到根DOM被选中了。

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

在代码中添加“:last”选择器来解决这个问题。

【讨论】:

  • This works best when the selector returns multiple results and you need to narrow it down to a specific element where you have no "Id" attribute to reference.
【解决方案5】:

我认为最好的方法。

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

【讨论】:

    【解决方案6】:

    伙计们,我知道这已经过时了,但是我有这个解决方案,我认为它比所有解决方案都好用。首先是克服了 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()
    

    希望不久的将来有人会发现它有帮助。

    【讨论】:

    • 很好地使用了filter,因为我需要完全匹配$(this).text() == text
    【解决方案7】:

    下面的 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>

    【讨论】:

    • 这是最好的答案!
    【解决方案8】:

    到目前为止,所有答案都不匹配包含 direct 子文本节点的 all specific 元素,该子文本节点包含 specific 文本。

    考虑以下示例。我们要查找所有的hobbit,即所有包含直接子文本节点的divs,其中包含单词“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 的回答:Tolkien、Gandalf、Bilbo、Frodo、Samweis、Gollum、Odo
    • 莫格斯的回答:托尔金
    • yoav barnea 的回答:甘道夫,佛罗多
    • Nicholas Sushkin 的回答:Samweis、Gollum、Odo
    • Rocket Hazmat 在 cmets 中的回答,Terry Lin 的回答,rplaurindo 的回答:Odo

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      相关资源
      最近更新 更多