How to replace lots of words in AJAX-driven page text, and in select attributes — using a Tampermonkey script?

前端 未结 1 1609
[愿得一人]
[愿得一人] 2020-12-07 05:22

I\'m translating text/words/terms inside an HTML document using a tree walker to affect only text nodes:

var replaceArry = [
    [/View your user account/gi         


        
相关标签:
1条回答
  • 2020-12-07 06:22

    To handle AJAX content, you can either use MutationObservers or polling with a timer. The former can get tricky and complicated, while the timer is simple, robust, and works well for most all practical applications.

    To handle attributes like placeholder, merely use document.querySelectorAll("[placeholder]") to get the nodes and loop through the resulting NodeList.

    While you are at it, you'll probably want to translate title attributes too.

    In short:

    • Put the replacement code in a function.
    • Call that function inside a setInterval.
    • Add a separate loop, inside the interval, for the attributes you want to change.

    Putting it all together, the cross-browser userscript would look like the following. See the inline comments and
    you can test the script against 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;
                      //-- 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";
        }
    }
    
    0 讨论(0)
提交回复
热议问题