编辑:我的 Chrome 浏览器出现问题并与我的脚本发生冲突,完全重新安装消除了问题源。如果我碰巧发现是什么原因造成的,我会把它包括在这里。
EDIT2:只是为了让在 2017 年阅读本文的任何人都知道我没有忘记这一点,而且自从我上次编辑以来我从未遇到过这个问题。
EDIT3:现在是 2019 年,到目前为止我再也没有遇到过这个问题。
我一直在学习如何创建一个简单的 Chrome 扩展,它是一个用户脚本端口。该脚本与 Tampermonkey 完美配合,将 run at
设置为 document-start
,所有需要从头开始捕获的必要事件都被捕获。
但是,当我在 Chrome 扩展程序中设置相同的设置时,我发现相同的运行设置比 Tampermonkey 的设置更快,这导致第一个函数失败:(Uncaught TypeError: Cannot call method 'appendChild' of null.
) 因为它试图将脚本元素附加到 head
部分,该部分直到 0.010 秒后才存在。
到目前为止,我的肮脏解决方案一直是使用 setInterval
函数并将计时器设置为 10 来检查 document.head
是否存在,然后继续执行代码如果条件为真。
有什么方法可以让我正确地工作而不必求助于 setInterval
或复制 Tampermonkey 的 grant none
选项,该选项似乎在网页上运行用户脚本上下文?
以下是我的 manifest.json 文件:
{
"manifest_version": 2,
"content_scripts": [ {
"js": [ "simpleuserscript.user.js" ],
"matches": [ "https://www.google.com/*"],
"run_at": "document_start"
} ],
"converted_from_user_script": true,
"description": "Chrome extension",
"name": "Testing",
"version": "1"
}
如果 Chrome 采用 afterscriptexecute
事件,所有这一切都可以避免,但在此之前,我只能使用 load
事件。我提前感谢提供的任何帮助。
编辑:我已经尝试过回复中的建议:使用不同的run at
点,使用DOMContentLoaded
并附加到document.documentElement
。全部都不成功,因为:1 和 2 使脚本错过了早期事件,并且 3 返回与尝试附加到 document.head
时相同的 TypeError。
脚本必须在 document.readyState = loading
时插入/运行,否则它会错过早期必要的事件,但不会太早到无法将子项附加到 的地步>documentElement
或head
simpleuserscript.user.js
中的代码示例:
var script = document.createElement("script");
script.textContent = "console.log('success')";
if(document.head) {
document.head.appendChild(script);
} else if(document.documentElement) {
document.documentElement.appendChild(script);
}
控制台将显示 TypeError: Cannot call method 'appendChild' of null
最佳答案
Chrome 扩展 内容脚本(从 manifest.json
运行)在 document_start
运行, 确实在 document.readyState
Doc之前触发已达到interactive
-- 这是您最早想要开始处理大多数页面元素的时间。
但是,你可以注入(inject)大部分<script>
如果您愿意,请立即使用节点。只是不要 document.head
或 document.body
因为它们还不存在。
附加到 documentElement
反而。例如:
var s = document.createElement ("script");
s.src = "http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js";
s.async = false;
document.documentElement.appendChild (s);
或者
var s = document.createElement ("script");
s.src = chrome.extension.getURL ("MyPwnCode.js");
s.async = false;
document.documentElement.appendChild (s);
如果您要添加或修改其他 DOM 元素,请在运行于 document_start
的脚本中, 等到 DOMContentLoaded
像这样的事件:
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
function fireContentLoadedEvent () {
console.log ("DOMContentLoaded");
// PUT YOUR CODE HERE.
//document.body.textContent = "Changed this!";
}
关于javascript - Chrome 扩展设置为 `run_at` `document_start` 运行速度太快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28186349/