Highlight a word of text on the page using .replace()

后端 未结 2 519
予麋鹿
予麋鹿 2020-12-11 22:35

I\'m developing a Google Chrome extension that allows you to automatically apply a highlighting CSS rule to a word that you choose.

I have the following code

2条回答
  •  误落风尘
    2020-12-11 23:14

    The error I was experiencing was due to a recursive loop because, for instance, I was looking for the keyword teste and I was inserting a new element with the content teste which would force the script to try to replace the new keyword teste again and so on.

    I came up with this function:

    function applyReplacementRule(node) {
        // Ignore any node whose tag is banned
        if (!node || $.inArray(node.tagName, hwBannedTags) !== -1) { return; }
    
        try {
            $(node).contents().each(function (i, v) {
                // Ignore any child node that has been replaced already or doesn't contain text
                if (v.isReplaced || v.nodeType !== Node.TEXT_NODE) { return; }
    
                // Apply each replacement in order
                hwReplacements.then(function (replacements) {
                    replacements.words.forEach(function (replacement) {
                        //if( !replacement.active ) return;
                        var matchedText = v.textContent.match(new RegExp(replacement, "i"));
    
                        if (matchedText) {
                            // Use `` instead of '' or "" if you want to use ${variable} inside a string
                            // For more information visit https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
                            var replacedText = node.innerHTML.replace(new RegExp(`(${replacement})`, "i"), "$1");
    
                            node.innerHTML = replacedText;
                        }
                    });
                }).catch(function (reason) {
                    console.log("Handle rejected promise (" + reason + ") here.");
                });
    
                v.isReplaced = true;
            });
        } catch (err) {
            // Basically this means that an iframe had a cross-domain source
            if (err.name !== "SecurityError")
            { throw err; }
        }
    }
    

    Where I modify the node property and "tell" that I've already modify that node so I don't end up on a recursive infinite loop again.

    P.S. As you can see this solution uses jQuery. I'll try to rewrite this to use just Vanilla JS.

提交回复
热议问题