我希望将名为“mylist”的 .json 列表中的字符串与任何网页上出现的仅可见字符串进行匹配。匹配的字符串将替换为脚本中下面的术语“REPLACED!”。
最重要的是脚本应该在现代浏览器上运行并且不会降低页面加载性能。所以我很感激任何优化建议!
这是我到目前为止所得到的:
@resource mylist https://example.com/mylist.json
(function(){
var mylist = JSON.parse(GM_getResourceText("mylist"));
var regexp = new RegExp('\\b(' + mylist.join('|') + ')\\b(?!\\)\\))', "gi");
function walk(node) {
var child, next;
switch ( node.nodeType )
{
case 1:
case 9:
case 11:
child = node.firstChild;
while ( child )
{
next = child.nextSibling;
walk(child);
child = next;
}
break;
case 3:
handleText(node);
break;
}
}
function handleText(textNode) {
textNode.nodeValue = textNode.nodeValue.replace(regexp, 'REPLACED!');
}
walk(document.body);
})();
我在这里做了一个示例:https://jsfiddle.net/xgnocwbq/
我面临的最大问题是,在某些页面上,脚本可以工作。对于其他人来说,它根本不起作用。例如,在 Qwant 搜索结果上,我的代码根本不起作用。但在 Google 搜索结果中,确实如此。
首先,您的代码中存在一些主要问题:
动态内容:Google 或 Facebook 等网站使用
AJAX
等特殊方法来刷新和更新内容,而无需重新加载整个页面。您的代码仅在页面首次加载时查看一次。如果稍后页面上出现更多内容,您的代码将看不到它。通过使用 MutationObserver
,您可以轻松处理动态内容。
性能:当前您正在遍历每个节点,这在具有大量 DOM 元素的页面上可能会很慢。使用
document.querySelectorAll
来提高性能。它只抓取文本节点,这是一种更快的方法。
这是代码的调整版本:
@resource mylist https: //example.com/mylist.json
(function() {
var mylist = JSON.parse(GM_getResourceText("mylist"));
var regexp = new RegExp('\\b(' + mylist.join('|') + ')\\b(?!\\)\\))', "gi");
function handleText(textNode) {
textNode.nodeValue = textNode.nodeValue.replace(regexp, 'REPLACED!');
}
function processNode(node) {
if (node.nodeType === 3) {
handleText(node);
} else {
let childNodes = node.querySelectorAll('*');
childNodes.forEach(processNode);
}
}
// Processes the initial page content
processNode(document.body);
// Observes the changes in the DOM to handle dynamic content
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach(processNode);
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
})();
如果经过改进的脚本在某些网站上仍然无法运行,则必须使用浏览器开发人员工具仔细检查该网站,以了解其特定行为或可能干扰您的代码的障碍。