javascript - How to replace lots of terms in AJAX-driven page text, and in select attributes -- using a Tampermonkey script? -
i'm translating text inside html document using tree walker affect text nodes:
var replacearry = [ [/view user account/gi, 'tu cuenta'], // etc. ]; var numterms = replacearry.length; 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 j = 0; j < numterms; j++) { oldtxt = oldtxt.replace (replacearry[j][0], replacearry[j][1]); } txtnode.nodevalue = oldtxt; }
works on static pages (and doesn't bust hyperlinks or event handlers), want also:
- catch ajax'd-in content
- replace text in
placeholder
attributes
how do without resorting regex , mucking things up?
to handle ajax content, can either use mutationobserver
s or polling timer. former can tricky , complicated, while timer simple, robust, , works practical applications.
to handle attributes placeholder
, merely use document.queryselectorall("[placeholder]")
nodes , loop through resulting nodelist.
while @ it, you'll want translate title
attributes too.
in short:
- put replacement code in function.
- call function inside
setinterval
. - add separate loop, inside interval, attributes want change.
putting together, cross-browser userscript following. see inline comments and
can test script against this jsfiddle page.
// ==userscript== // @name replace lots of terms on ajax'd page // @include http://fiddle.jshell.net/hp6k2/show/* // @grant none // ==/userscript== var replacearry = [ [/text/gi, 'blather'], [/view user account/gi, 'tu cuenta'], // etc. ]; var numterms = replacearry.length; //-- 5 times/second; plenty fast. var transtimer = setinterval (translatetermsonpage, 222); function translatetermsonpage () { /*--- replace text on page without busting links or javascript functionality. */ var txtwalker = document.createtreewalker ( document.body, nodefilter.show_text, { acceptnode: function (node) { //-- skip whitespace-only nodes 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; } // //--- replace user-visible attributes. // var placeholdernodes = document.queryselectorall ("[placeholder]"); replacemanyattributetexts (placeholdernodes, "placeholder"); var titlenodes = document.queryselectorall ("[title]"); replacemanyattributetexts (titlenodes, "title"); } function replaceallterms (oldtxt) { (var j = 0; j < numterms; j++) { oldtxt = oldtxt.replace (replacearry[j][0], replacearry[j][1]); } return oldtxt; } function replacemanyattributetexts (nodelist, attributename) { (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 not match nodelist in replacemanyattributetexts"; } }
Comments
Post a Comment