如何在无限滚动页面上重复 运行 Chrome 扩展代码

How to run Chrome extension code repeatedly on infinite scroll pages

这是我的第一个 Chrome 扩展。我正在构建一个扩展来替换页面上的文本。

提供的代码适用于加载 DOMContent 加载的任何内容。但是,在使用某种无限滚动的页面上,当加载新内容时不会发生文本替换。

我需要它 运行 对以后添加到页面的任何内容进行文本替换。

我曾尝试使用 onscroll 事件侦听器,但这既笨拙又昂贵。我相信有更好的方法。

我研究过使用清单 run_at,但一直无法找到使用它的方法。

let elements = document.getElementsByTagName('*');
let replacements = {
    "first to replace": "new text",
    "second to replace": "also new text"
};
let keys = Object.keys(replacements);

 RegExp.quote = (str) => {
     return str.replace(/([.?*+^$[\]\(){}|-])/g, "\");
 };

let makeItAwesomer = () => {
    for (var i = 0; i < elements.length; i++) {
        var element = elements[i];

        for (var j = 0; j < element.childNodes.length; j++) {
            let node = element.childNodes[j];

            if (node.nodeType === 3) {
                let text = node.nodeValue;
                let newText = text;

                if(keys.some(function(key){ 
                    return ~text.toLowerCase().indexOf(key.toLowerCase());
                })){

                    keys.forEach( key => {
                        let regex = new RegExp(RegExp.quote(key), "gi");
                        newText = newText.replace(regex, replacements[key]);
                    });

                    if (newText != text) {
                        element.replaceChild(document.createTextNode(newText), node);
                    }
                }
            }
        }
    }
}

makeItAwesomer();

您可以使用内置的 MutationObserver 来检测 DOM 何时发生变化,甚至可以自定义它以仅检测 DOM 结构的变化(例如新节点添加到无限滚动页面)并忽略其他更改(例如属性更改,有时只需将鼠标悬停在某处即可发生)。你可以有这样的东西:

const targetNode = document.body;

// Options for the observer (which mutations to observe)
// Set attributes to false if you do not care if existing nodes have changed,
//  otherwise set it true. 
const config = { attributes: false, childList: true, subtree: true };

// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
    makeItAwesomer();
};

// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

这可能适用于您现在编写的代码,只要 makeItAwesomer() 正确检测到哪些文本已被修改(如果它适用于 onScroll 事件,则应该如此)。

但是,为了提高效率,如果您重新编写 makeItAwesomer() 函数以获取要更改的节点的参数,则可以修改回调以使其仅更新新加载的节点。所以 callback 更像是:

const callback = function(mutationsList, observer) {
    for(let mutation of mutationsList) {
        makeItAwesomer(mutation);
    }
};

Here's the MDN Web docs on MutationObserver 以帮助更好地理解其工作原理。