: contains () does not return the expected nodes

Please consider the following code:

// @include /(^https?:\/\/www\.|^https?:\/\/)google\.com(\.|\/).*/ // @include /(^https?:\/\/www\.|^https?:\/\/)stackoverflow\.com\/.*/ // @include /(^https?:\/\/www\.|^https?:\/\/)userscripts-mirror\.org\/.*/ // @include http://wiki.greasespot.net/* // @version 1.0 // @require https://code.jquery.com/jquery-2.1.1.min.js // @grant GM_addStyle $ ( 'body:contains("serscripts.org")').each ( function () { var results = $(this); var text = results.text(); console.log(text); text = text.replace( /serscripts\.org/ig, "serscripts-mirror.org" ); text = text.replace( /(:8080|%3A8080)/ig, ""); //results.text ( text ); } ); 

I expected that the return should only be elements containing this string, but the result on the console is all the body text.


Consider this page in a row:

 // @updateURL https://userscripts.org/scripts/so... 

I want to change that.


Or this one :

 // @require http://userscripts.org/scripts/source... 

I would also like to change.


All words between tags should be checked for the string and only return those that it has.

What is the correct selector for this?


Note :
Link attributes and text between <a></a> have already been changed using a similar .each ( function ) .

+1
source share
1 answer

:contains returns exactly what is expected. From specification :

Corresponding text can be displayed directly in the selected element in any of these descendants of the elements or combination .


In general, to replace, wrap, or highlight text conditions on a web page, you need to work at the TEXT_NODE level. Everything else runs the risk of sorting out: URL, id, event handler, etc.

You can use Tree Walker for this:

 var txtWalker = document.createTreeWalker ( document.body, NodeFilter.SHOW_TEXT, { acceptNode: function (node) { //-- Skip whitespace-only nodes if (node.nodeValue.trim() ) return NodeFilter.FILTER_ACCEPT; return NodeFilter.FILTER_SKIP; } }, false ); var txtNode = null; while (txtNode = txtWalker.nextNode () ) { var oldTxt = txtNode.nodeValue; var newTxt = oldTxt.replace (/serscripts\.org/ig, "serscripts-mirror.org"); newTxt = newTxt.replace (/(:8080|%3A8080)/ig, ""); txtNode.nodeValue = newTxt; } 

this will safely take care of everything on the page except for HTML attributes like href , src , etc.

If you want to change them, use the separate target .each () code, as you said, what you are doing, but do not change the text between <a></a> , as was already done with walker.

+2
source

All Articles