开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜