问题
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 the return should be just the elements containing that string, but the result on the console is all the text of the body.
Consider this page at line:
// @updateURL https://userscripts.org/scripts/so...
I want to change that.
Or this one :
// @require http://userscripts.org/scripts/source...
I'd like to change too.
All words between tags should be checked for the string, and return only the ones that have it.
What is the right selector for this?
Note:
Link attributes and text between <a></a> are already changed using a similar .each ( function ).
回答1:
:contains is returning exactly what is expected. From the spec:
The matching text can appear directly within the selected element, in any of that element's descendants, or a combination thereof.
In general, to replace, wrap or highlight text terms on a web page, you need to work at the individual TEXT_NODE level. Anything else risks trashing: URL's, id's, event handler's, etc.
You can use a 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 wish to change those, use separate, targeted .each () code -- like you said you were doing -- but do not change the text between <a></a> as that will already have been done by the tree walker.
来源:https://stackoverflow.com/questions/25613081/contains-does-not-return-the-expected-nodes