gpt4 book ai didi

javascript - Chrome 内容脚本不工作 : DOMContentLoaded listener does not execute

转载 作者:可可西里 更新时间:2023-11-01 02:36:07 26 4
gpt4 key购买 nike

我正在尝试编写可纠正 1 个论坛上拼写错误的扩展程序。

我正在尝试访问 <p>标签,带有内容脚本,但它不会改变任何东西(使用下面的代码):

document.addEventListener("DOMContentLoaded", function() {
document.getElementsByTagName("P")[4].innerHTML = "correct_word";
});

作为扩展添加时它不会改变任何东西,显然如果我 wget该页面,并将脚本放在那里,一切正常。有什么想法吗?

我的 manifest.json 文件:

{
"manifest_version": 2,
"name": "Extension",
"description": "Description",
"version": "1.0",
"content_scripts": [{
"run_at": "document_end",
"matches": ["http://example.com/"],
"js": ["script.js"]
}],
"web_accessible_resources": ["Filedeleted(really).html"]
}

我知道内容脚本和 WWW 页面有不同的沙箱,也许内容脚本无法访问页面(和标签)?

最佳答案

您正在监听触发事件(在本例中为 DOMContentLoaded )之后注入(inject)脚本。因此,您在监听器中的任何代码都不会执行,因为在您添加监听器后该事件永远不会触发。

在 Chrome 扩展和 Firefox WebExtensions 中,当为 content script 指定时间时要被注入(inject),你可以指定"document_start""document_end",或者"document_idle"1manifest.json 这是为 run_at 属性声明的值。对于 tabs.executeScript() ,它是 runAt 属性。

  • document_start
    注入(inject)发生在创建 DOM 或运行页面脚本之前。这意味着 document.bodydocument.head 还不存在。 DOMContentLoadedwindow load 事件尚未触发。您可以通过将内容添加到 document.documentElement 来将内容添加到 DOM。您可能需要使用 MutationObserver观察您有兴趣添加到 DOM 的元素,或等待 DOMContentLoaded 之类的事件来指示 DOM 可用。
  • document_end(默认)
    注入(inject)发生在 DOM 完成之后,但在加载子资源(例如图像和框架)之前。这通常发生在 DOMContentLoaded 触发之后,但在 window load 事件触发之前。
  • document_idle
    注入(inject)发生在 document_end 之后的某个时间,紧接在 window load 事件触发之后。 answer to "When does a run_at: document_idle content script run?"表示这是较早的:

    • window load 事件触发后,或者
    • DOMContentLoaded 事件触发后 200 毫秒。

    这意味着您的内容脚本将在 DOMContentLoaded 触发后被注入(inject),但是 window load 事件可能有也可能没有已经解雇了。

监听DOMContentLoaded时, 或 window load, 你应该检查 document.readyState第一

任何时候你使用一个DOMContentLoaded监听器,或者一个windowload监听器,你应该总是检查document.readyState在添加监听器之前,确保您在 DOMContentLoaded 事件被触发之前添加监听器(或者在 load 事件被触发之前,如果那是您正在收听)。当您想监听这些事件时,这应该是正常的习惯。如果您在事件触发后添加监听器,监听器将永远不会运行。

要添加一个 DOMContentLoaded 监听器,您应该使用如下内容:

if(document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded',afterDOMLoaded);
} else {
afterDOMLoaded();
}

function afterDOMLoaded(){
//Everything that needs to happen after the DOM has initially loaded.
}

要添加一个 window load 监听器,您可以使用如下内容:

if(document.readyState !== 'complete') {
window.addEventListener('load',afterWindowLoaded);
} else {
afterWindowLoaded();
}

function afterWindowLoaded(){
//Everything that needs to happen after the window is fully loaded.
}

  1. 如果您正在使用 tabs.executeScript(),您为 runAt 提供的值仅表示您希望脚本注入(inject)的最早时间。如果您在此时间之前执行 tabs.executeScript(),则注入(inject)会延迟到指定时间。请注意,对于 document_start,执行 tabs.executeScript() 时对新页面有效的时间点是一个复杂的主题,值得单独提问/回答。
  2. 此答案的部分内容复制自 my answer to "Detect and handle a button click in the active HTML page" .

关于javascript - Chrome 内容脚本不工作 : DOMContentLoaded listener does not execute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43233115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com