javascript - 如何在不先加载原始文本的情况下替换网页上的文本?
问题描述
我正在尝试为浏览器扩展找到正确的 JavaScript 代码,将网页文本中的“冬季”一词替换为“夏季”一词。
第一次尝试
根据这篇博文,我的第一次尝试是
function wordFilter() {
let target = "winter";
let replace = "summer";
var html = document.querySelector('html');
var walker = document.createTreeWalker(html, NodeFilter.SHOW_TEXT);
var node;
while (node = walker.nextNode()) {
node.nodeValue = node.nodeValue.replace(target, replace);
}
}
wordFilter()
这几乎可以工作。它确实将“冬天”替换为“夏天”,但“冬天”这个词在被替换之前仍会出现在屏幕上几秒钟。我希望过滤器从一开始就起作用。
至少,这个尝试表明我的一般扩展设置权限是正确的,所以任何进一步的失败都必须是代码问题。
第二次尝试
我的第二次尝试是基于对StackOverflow 帖子的这个答案。这是一个涉及的帖子,但“添加节点的朴素枚举”下的部分最接近我想要的。函数中的代码onMutation()
搜索<h1>
包含目标文本的元素;只是为了概念验证,我简化了这部分代码以应用于作为添加元素的后代的所有元素。如果初始 DOM 加载符合一组 Mutations (我仍然不清楚,但从似乎是预期行为的上下文中),那么这应该捕获页面上的每个元素和每段文本。
编码:
var observer = new MutationObserver(onMutation);
observer.observe(document, {
childList: true, // report added/removed nodes
subtree: true, // observe any descendant elements
});
function onMutation(mutations, observer) {
for (var i = 0, len = mutations.length; i < len; i++) {
var added = mutations[i].addedNodes;
for (var j = 0, node; (node = added[j]); j++) {
replaceText(node);
}
}
}
function replaceText(el) {
let target_string = "winter";
let replacement_string = "summer";
const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
for (let node; (node = walker.nextNode());) {
const text = node.nodeValue;
const newText = text.replace(target_string, replacement_string);
if (text !== newText) {
node.nodeValue = newText;
}
}
}
这根本不起作用。在任何情况下,任何时候都不会用任何东西代替“冬天”这个词的任何实例。
现在我不知所措了。如何替换网页上的文本而不在替换之前出现原始文本?
解决方案
我可以确认wOxxOm 选择的方法(在我的帖子中链接)运行良好,包括我尝试使用的方法。
这种情况下的问题是浏览器插入代码的时间。
manifest.json
允许一个"content_scripts"
键"run_at"
指定浏览器何时应该加载内容脚本(更多内容见MDN)。默认值为"document_idle"
,这似乎意味着“只要有机会”。
使用此默认设置,浏览器正在加载页面,然后等待直到它有空闲时刻加载扩展脚本以开始查找 Mutations。因此,MutationObserver 错过了所有初始突变,脚本似乎无法正常工作。(顺便说一句:我现在确信每个 DOM 元素的初始加载确实算作DOM的突变)。
通过"run_at": "document_start"
像manifest.json
这样指定:
"content_scripts": [
{
"js": ["filename.js"],
"run_at": "document_start"
}
]
浏览器在开始加载 DOM 时立即运行脚本来监视 Mutations,因此会捕获初始的 Mutations,并且在加载之前更改文本,以便原始的“冬天”在更改为“之前不会出现在页面上”夏天”。
特别感谢@Jason Goemaat 的提示。
推荐阅读
- python-3.x - 如何使用 selenium 从网站上的某个类获取链接
- javascript - WebRTC STUN/TURN 分配请求超时
- javascript - 将多个输入序列化为单个参数
- java - Spring Boot 数据休眠事务管理器
- image - React Native Image 组件不会在 iOS 14 上从外部 url 渲染图像
- python - 无法使用 Zoom API 创建会议(响应代码 200)
- pine-script - 如果警报条件为真,如何在图表上绘制形状
- extjs - 分机 JS | 下载带有附加数据的图表
- javascript - 通过 Javascript 将 PDF 转换为“仅图像”
- java - 如何在类之间调用数组?