我正在使用树浏览器仅影响文本节点来翻译HTML文档中的文本/单词/术语:
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; }
这在静态页面上效果很好(并且不会破坏超链接或事件处理程序),但我还希望它:
placeholder
要处理AJAX内容,可以使用MutationObservers或使用计时器进行轮询。前者会变得棘手和复杂,而计时器则简单,健壮,并且对于大多数实际应用都适用。
MutationObserver
要处理类似的属性placeholder,只需使用document.querySelectorAll("[placeholder]")获取节点并遍历生成的 NodeList即可 。
document.querySelectorAll("[placeholder]")
当您使用它时,您可能还需要转换title属性。
title
简而言之:
setInterval
放在一起,跨浏览器用户脚本将如下所示。查看内联注释, 您可以 针对 此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"; } }