Chrome 扩展设置为 `run_at` `document_start` 运行速度太快? [英] Chrome extension set to `run_at` `document_start` is running too fast?
问题描述
我的 Chrome 浏览器出现问题并与我的脚本产生冲突,完全重新安装消除了任何问题来源.如果我碰巧找出导致它的原因,我会将其包含在此处.
Something was wrong with my Chrome browser and creating a conflict with my script, a full reinstall eliminated whatever the problem source was. If I happen to find out what was causing it I will include it in here.
只是为了让任何在 2017 年读到这篇文章的人都知道我没有忘记这一点,而且自从我之前的编辑以来我从未遇到过这个问题.
Just to let anyone reading this in 2017 know that I haven't forgotten this and I have never had this problem since my previous edit.
现在是 2019 年,到目前为止我再也没有遇到过这个问题.
It is 2019 and so far I've never had this problem again.
我一直在学习如何创建一个简单的 Chrome 扩展程序,它是一个用户脚本端口.该脚本与 Tampermonkey 完美配合,将 run at
设置为 document-start
,所有需要从头捕获的必要事件都被捕获.
I have been learning how to create a simple Chrome extension which is a userscript port. The script works perfectly with Tampermonkey with the setting run at
to document-start
, all the necessary events that need to be caught from the beginning are all captured.
然而,当我在 Chrome 扩展中设置相同的设置时,我发现相同的运行设置比 Tampermonkey 的要快,这导致第一个函数失败:(Uncaught TypeError: Cannot call method 'appendChild' of null.
),因为它试图将脚本元素附加到 head
部分,该部分直到 0.010 秒后才存在.
However, when I set the same settings in the Chrome extension I discovered that the same running setting is faster than Tampermonkey's which causes the first function to fail: (Uncaught TypeError: Cannot call method 'appendChild' of null.
) since it tries to append a script element to the head
section, which doesn't exist until 0.010s later.
到目前为止,我的肮脏解决方案是使用 setInterval
函数并将计时器设置为 10 来检查 document.head
是否存在,然后继续执行代码如果条件为真.
My dirty solution so far has been to make use of a setInterval
function with the timer set to 10 to check if document.head
exists and then proceed with the code if the condition is true.
有什么方法可以使我正常工作而不必求助于 setInterval
或者复制 Tampermonkey 的 grant none
选项,该选项似乎在网页上运行用户脚本上下文?
Is there any way that I can make this work correctly without having to resort to setInterval
or maybe replicate Tampermonkey's grant none
option which appears to run the userscript on the webpage context?
以下是我的 manifest.json 文件:
The following is my manifest.json file:
{
"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
事件.我预先感谢您提供的任何帮助.
All of this could be avoided if Chrome would adopt the afterscriptexecute
event, but until that happens I am stuck with the load
event. I thank in advance any help provided.
我已经尝试了回复中的建议:使用不同的 run at
点,使用 DOMContentLoaded
并附加到 document.documentElement
.一切都不成功,因为:1 和 2 使脚本错过早期事件,3 返回与尝试附加到 document.head
时相同的 TypeError.
I have already tried the suggestions in the replies: using a different run at
point, using DOMContentLoaded
and append to document.documentElement
. All were unsuccessful because: 1 and 2 makes the script miss early events, and 3 returns the same TypeError as when trying to append to document.head
.
必须在 document.readyState = loading
时插入/运行脚本,否则它会错过早期必要的事件,但不会太早以至于无法将孩子附加到 documentElement
或 head
The script has to be inserted/running when document.readyState = loading
or else it will miss early necessary events, but not so early to the point of being unable to append childs to either documentElement
or 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
, do 在 document 之前触发.readyState
Doc 已经达到了 interactive
-- 这是您想要开始处理大多数页面元素的最早时间.
Chrome extension Content scripts (run from a manifest.json
) that are run at document_start
, do fire before document.readyState
Doc has reached interactive
-- which is the earliest you want to start messing with most page elements.
但是,如果您愿意,您可以立即注入大多数 节点.只是不要
document.head
或 document.body
因为它们还不存在.
改为附加到 documentElement
.例如:
However, you can inject most <script>
nodes right away if you wish. Just not to document.head
or document.body
because they don't exist yet.
Append to documentElement
instead. For example:
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
事件,如下所示:
If you are adding or modifying other DOM elements, in a script running at document_start
, wait until the DOMContentLoaded
event like so:
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
function fireContentLoadedEvent () {
console.log ("DOMContentLoaded");
// PUT YOUR CODE HERE.
//document.body.textContent = "Changed this!";
}
这篇关于Chrome 扩展设置为 `run_at` `document_start` 运行速度太快?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!