如何在无限滚动页面上重复 运行 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 以帮助更好地理解其工作原理。
这是我的第一个 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 以帮助更好地理解其工作原理。