Comment remplacer beaucoup de termes dans le texte de la page par AJAX et dans certains attributs – en utilisant un script Tampermonkey?

Je traduis le texte dans un document HTML en utilisant un marcheur d'arbre pour affecter uniquement les noeuds de texte:

var replaceArry = [ [/View your 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; for (var J = 0; J < numTerms; J++) { oldTxt = oldTxt.replace (replaceArry[J][0], replaceArry[J][1]); } txtNode.nodeValue = oldTxt; } 

Cela fonctionne bien sur les pages statiques (et il ne perturbe pas les hyperliens ou les gestionnaires d'événements), mais je le veux aussi:

  • Capturez le contenu AJAX
  • Remplacer le texte en attributs de l' placeholder

Comment puis-je faire cela sans recourir à RegEx et vraiment en train de faire des choses ?

Pour gérer le contenu AJAX, vous pouvez soit utiliser MutationObserver s ou polling avec une minuterie. Le premier peut s'avérer délicat et compliqué, tandis que la minuterie est simple, robuste et fonctionne bien pour la plupart des applications pratiques.

Pour gérer les attributs comme placeholder , utilisez simplement document.querySelectorAll("[placeholder]") pour obtenir les nœuds et faire passer la NodeList résultante.

Pendant que vous êtes là, vous voudrez probablement également traduire les attributs de title .

En bref:

  • Placez le code de remplacement dans une fonction.
  • Appelez cette fonction dans un setInterval .
  • Ajoutez une boucle distincte, dans l'intervalle, pour les attributs que vous souhaitez modifier.

Tout en rassemblant, l'utilisateur de cross-browser ressemble à ce qui suit. Voir les commentaires en ligne et
Vous pouvez tester le script sur cette page jsFiddle .

 // ==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; //-- 5 times/second; Plenty fast. var transTimer = setInterval (translateTermsOnPage, 222); function translateTermsOnPage () { /*--- Replace text on the 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; } // //--- Now replace 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"; } }