我正在编写的扩展程序在页面加载开始时触发内容脚本,使用:
"run_at": "document_start"
这很好用。但是,我需要注射"一些东西,然后继续渲染初始页面。如果我的动作脚本只包含:
alert("Hello World");
警报将会触发,页面将继续呈现。相反,如果动作脚本包含:
document.write("<span>Hello World!</span>");
这将写出&#34; Hello World!&#34;但不会继续呈现页面。我知道&#34; document.write&#34;几乎从来都不是一个好工具,但它似乎是正确的工具,因为(a)它在DOM的其余部分之前的写作和(b)在dom中没有任何元素来改变&#34;实现注射。
我认为这很好地解释了这种情况。但我会提供更多的背景信息。最终我想&#34;注射&#34;一个iframe将加载&#34;在前面&#34;有问题的页面。尝试为我的扩展程序的用户提供特定网站的替代用户体验。
答案 0 :(得分:0)
好吧,在 <body>
存在之前,我没有看到写入文档的重点,但是你可以使用DOM操作来执行此操作,而不是document.write
:
var el = document.createElement("span");
el.textContent = "Hello, World!";
document.documentElement.appendChild(el);
这不会阻止后续的DOM解析。
如果要符合标准页面结构并将其添加到body元素,可以添加MutationObserver
以等待它(尽管这可能不会比"document_end"
注入更好):
var observer = new MutationObserver(function(mutations) {
mutations.find(function(mutation) {
for (var i = 0; i < mutation.addedNodes.length; i++) {
if(mutation.addedNodes[i].nodeName === "BODY") {
var el = document.createElement("span");
el.textContent = "Hello, World!";
// Clunky way to prepend a node
mutation.addedNodes[i].insertBefore(el, mutation.addedNodes[i].firstChild);
observer.disconnect();
return true; // Early termination of find()
}
}
});
});
observer.observe(document.documentElement, {childList: true});