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

有人能告诉我是否有可能根据其内容而不是ID找到一个元素吗?

我试图找到没有不同的类或id的元素。(然后我需要找到该元素的父元素。)

438461 次浏览

是的,使用jQuery contains选择器。

你可以使用: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>

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

火箭的回答不管用。

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

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

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

在代码中添加":去年"选择器来修复此问题。

在我看来是最好的办法。

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

伙计们,我知道这很老了,但是我有一个解决办法,我认为它比所有方法都管用。首先克服了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()

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

下面的jQuery选择包含文本但没有子节点的div节点,这些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>

到目前为止,所有答案都不匹配包含直接子文本节点的所有 具体的元素,该节点包含具体的文本。

考虑下面的例子。我们想要找到所有的霍比特人,也就是说,所有包含直接子文本节点的divs,该节点包含单词“;霍比特人”;(包括单词边框,忽略大小写)。

$(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危险品的答案:托尔金,甘道夫,比尔博,佛罗多,山姆维斯,咕噜,厄多
  • Morgs的答案是:托尔金
  • yoav barnea的答案:甘道夫,弗罗多
  • Nicholas Sushkin的回答是:山姆维斯,咕噜,厄多
  • Rocket Hazmat在评论中的回答,Terry Lin的回答,rplurindo的回答:辛癸酸甘油酯

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