I've made two different attempts to replace all occurrences of a single word from a webpage using JQuery in a Chrome extension. Both attempts kind of worked, but neither worked as a universal method for replacing all occurrences of a word from a webpage.
How can I write a script that replaces all occurrences of a certain word in a webpage?
Read on for details of the 2 different attempts which both kind of worked but failed for different reasons.
Attempt 1: Replace the text of nodes that have no children. This fails in cases where child nodes are used for formatting. For example, it fails when parsing the following:
<p>StringToReplace <strong>doesn't</strong> get replaced!</p>
The exact code I used for this attempt is:
$("*").each(function () {
if ($(this).children().length == 0) {
$(this).text(replaceStrings($(this).text()));
}
}
(replaceStrings is a separate function with a bunch of arbitrary calls to replace)
Attempt 2: Replace the HTML of nodes that probably only contain text (e.g. p
). This fails because some of the webpages my script needs to work on have text appearing right inside tags like body. If I try replacing the HTML of body, it has an undesired side-effect of breaking functionality on some pages. IMO it would be a nightmare to try to handle every edge case where site functionality is impaired by replacing HTML of body
or div
s high up the DOM tree.
The code I used for this second attempt:
$("*").each(function () {
if (
$(this)[0].nodeName.toLowerCase() == "font"
|| $(this)[0].no开发者_开发技巧deName.toLowerCase() == "span"
|| $(this)[0].nodeName.toLowerCase() == "p"
//|| $(this)[0].nodeName.toLowerCase() == "body"
// || $(this)[0].nodeName.toLowerCase() == "div"
){
$(this).html(replaceStrings($(this).html()));
}
}
How can I write a script that replaces all occurrences of a certain word in a webpage?
Thanks!
I don't like the plugin in the first answer because it only works 1 level deep. Here's a version that goes through the entire structure under the selected element.
Usage: $(".content").replaceText("visitor","John Doe");
// Replace occurences of 'search' with 'replace' anywhere in the element.
// New HTML tags will be rendered, except if 'text_only' is true.
$.fn.replaceText = function(search, replace, text_only) {
return this.each(function(){
var v1, v2, rem = [];
$(this).find("*").andSelf().contents().each(function(){
if(this.nodeType === 3) {
v1 = this.nodeValue;
v2 = v1.replace(search, replace);
if(v1!=v2) {
if(!text_only && /<.*>/.test(v2)) {
$(this).before( v2 );
rem.push(this);
}
else this.nodeValue = v2;
}
}
});
if(rem.length) $(rem).remove();
});
};
I haven't thoroughly tested this, but it should point you in the right direction:
$('*', 'body')
.andSelf()
.contents()
.filter(function() {
return this.nodeType === 3;
})
.each(function() {
this.nodeValue = replaceStrings(this.nodeValue);
});
(based on this answer along with help from this plugin)
精彩评论