If you need to manage AJAX content, you have a couple of options. You can either utilize MutationObserver
s or implement polling with a timer. While the former approach may be more complex and intricate, using a timer is simpler, reliable, and suitable for most practical scenarios.
To handle attributes such as placeholder
, you can simply target them by using
document.querySelectorAll("[placeholder]")
to access the nodes and iterate through the resulting
NodeList.
Additionally, consider translating title
attributes as well.
In summary:
- Encapsulate the replacement code within a function.
- Invoke that function within a
setInterval
.
- Include a separate loop within the interval for the attributes you wish to modify.
Combining all these elements, the cross-browser userscript will resemble the example below. Review the inline comments and
you can experiment with the script on this jsFiddle page.
// ==UserScript==
// @name Replace lots of terms on an AJAX'd page
// @include http://fiddle.jshell.net/Hp6K2/show/*
// @grant none
// ==/UserScript==
var replaceArry = [
[/text/gi, 'blather'],
[/View your user account/gi, 'Tu cuenta'],
// etc.
];
var numTerms = replaceArry.length;
//-- Executes every 5 times per second; Adequately fast.
var transTimer = setInterval (translateTermsOnPage, 222);
function translateTermsOnPage () {
/*--- Substitutes text on the page without disrupting links or JavaScript
functions.
*/
var txtWalker = document.createTreeWalker (
document.body,
NodeFilter.SHOW_TEXT, {
acceptNode: function (node) {
//-- Skips nodes composed solely of whitespace
if (node.nodeValue.trim() ) {
if (node.tmWasProcessed)
return NodeFilter.FILTER_SKIP;
else
return NodeFilter.FILTER_ACCEPT;
}
return NodeFilter.FILTER_SKIP;
}
},
false
);
var txtNode = null;
while (txtNode = txtWalker.nextNode () ) {
txtNode.nodeValue = replaceAllTerms (txtNode.nodeValue);
txtNode.tmWasProcessed = true;
}
//
//--- Now replaces user-visible attributes.
//
var placeholderNodes = document.querySelectorAll ("[placeholder]");
replaceManyAttributeTexts (placeholderNodes, "placeholder");
var titleNodes = document.querySelectorAll ("[title]");
replaceManyAttributeTexts (titleNodes, "title");
}
function replaceAllTerms (oldTxt) {
for (var J = 0; J < numTerms; J++) {
oldTxt = oldTxt.replace (replaceArry[J][0], replaceArry[J][1]);
}
return oldTxt;
}
function replaceManyAttributeTexts (nodeList, attributeName) {
for (var J = nodeList.length - 1; J >= 0; --J) {
var node = nodeList[J];
var oldText = node.getAttribute (attributeName);
if (oldText) {
oldText = replaceAllTerms (oldText);
node.setAttribute (attributeName, oldText);
}
else
throw "attributeName does not match nodeList in replaceManyAttributeTexts";
}
}