How do I use jQuery to get a set of every element with certain text, but NOT the parents?
I want to use jQuery to select every element that has a certain text string in it, but not the parents of that element. How do I do this? I have no control whatsoever over the HTML code, but here is an example:
<body>
<div>
<p>This is a paragraph and <a>this is not</a>.</p>
Here we have a div.
</div>
</body>
If I use the word "this" as my match word, I want jQuery to provide me with a set containing th开发者_Go百科e <a>
and the <p>
, but not the <div>
or the <body>
.
Again, I have no control AT ALL over the HTML!
Thanks!
** Clarification: I do want the parent of the element if the parent ALSO has a "this" in its immediate text. Thus, I want the <a>
AND the <p>
.
Update::
Here is what I came up with: jsfiddle
var myArray = $('*:contains("this")','body').filter(function(){
if($(this).contents().filter(function(){
return(this.nodeType == 3);
}).text().indexOf('this')===-1){
return false;
}
return true;
});
$.each(myArray,function(){
console.log(this.nodeName);
});
Starts similar to the link posted by Robin, but it forces to only search in the context of body
elements - this keeps your scripts safe if they are not inline.
The next part is a filter that checks to see if the current element direct text nodes contain the text.
This is a bit convoluted, but to walk through it:
.contents()
- docs - gets the immediate nodes
.filter()
- docs - we want to only test on test nodes, so we filter them out
this.nodeType
- w3 spec - check to see if its a text node
.test()
- docs - gets a string of the text nodes.
.indexOf()
- check that string for our string
Note I did the :contains()
at the top and in the second filter, the first isn't needed per say but I think the initial test should reduce the number of deeper tests and speed it up slightly.
Here's my solution with pure JS.
Code:
function findElmsWithWord(word, elm, found){
if (elm.nodeType === 3 && elm.data.indexOf(word) !== -1)
found.push(elm.parentNode);
else
for (var i = 0; i < elm.childNodes.length; i++)
findElmsWithWord(word, elm.childNodes[i], found);
}
var elms = []; findElmsWithWord('this', document.body, elms); console.log(elms);
It recursively walks the dom until it finds the text nodes that contain the word in question. And then adds the text node's parent as a result.
精彩评论