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

标签 javascript google-chrome-extension dom-events infinite-scroll

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

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

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

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

我研究过使用 list 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, "\\$1");
 };

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以帮助更好地了解其工作原理。

关于javascript - 如何在无限滚动页面上重复运行 Chrome 扩展代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57313620/

相关文章:

google-chrome - Chrome 扩展程序可以更改 Chrome 设置(在新窗口/弹出窗口中打开)吗?

javascript - css如何设置选择框的样式

javascript - 如何从表单值创建 JSON?

javascript - 自定义 JSON.stringify 无法将对象作为一个整体进行字符串化,但在迭代一层时有效

javascript - webRequest 监听器看不到 'cookie' 、 'referer' 、 'origin' 等 header

javascript - 如何在 javascript 中正确初始化 ErrorEvent?

javascript - Java 流类似于 JavaScript 数组吗?

google-chrome - Chrome 扩展创建新标签并将消息从 popup.js 发送到新标签的内容脚本

javascript - 无法理解 node.js

javascript - 停止在另一个事件监听器中传播特定事件