扩展的脚本不会在 运行 之前等待整个页面加载

Extension's script does not wait for whole page to load before running

我最近开始开发 chrome 扩展,它必须等待 YouTube 页面加载,然后才能在现有代码中的特定位置添加按钮。

我已经使用 getElementById() 获取元素,但大多数时候我的页面没有时间完全加载脚本已经完成。

我检查了很多关于这个问题的主题,偶然发现 window.addEventListener('load', submitAction); 它实际上并没有等待 整个页面 加载,或者至少它没有看起来像。当我尝试打印 getElementById() 的输出时,结果是 null.

我一直在尝试使用其他类型的事件侦听器,在文档而不是 window 上使用它,试图等待 DOMContentLoaded,因为它看起来也在等待文档完全加载,但实际上没有任何东西等待整个页面加载。

我想做的最理想的事情是加载页面,当我正在寻找的元素加载时,我只需抓住它,创建一个按钮,附加它,它就会无缝地出现在页面中,没有任何延迟。

我是不是做错了什么?*

这是我的代码示例:

manifest.json :

{
    "name": "Name",
    "description": "Description.",
    "version": "1.0",
    "manifest_version": 2,
    "permissions": [
      "activeTab"
    ],
    "content_scripts": [
      {
        "matches": ["https://*.youtube.com/c/*"],
        "js": ["content-script.js"],
        "run_at": "document_idle"
      }
    ],
    "background": {
      "scripts": ["background.js"],
      "persistent": false
    }
}

background.js :

chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
  if (changeInfo.status == 'complete') {
    window.onload = function() {
      chrome.tabs.executeScript({
        file: "content-script.js"
      });
    }
  }
})

内容-script.js :

window.addEventListener('load', submitAction);

function submitAction()
{
  var youtubeName = document.getElementById("channel-name")

  console.log("========================")
  console.log(youtubeName)
  console.log("========================")
}

也许它没有帮助,但请尝试将“延迟”添加到您的脚本标签中:

<script defer src="script_file_name.js"></script>

defer 使您的 .js 文件等待整个 HTML 完成解析。

将您的代码附加到 document-idle,这是 最新的 run-at 值,将在 window.load 事件触发后立即触发:

The browser chooses a time to inject scripts between "document_end" and immediately after the window.onload event fires

source

如果 DOM 被元素 post 加载水合(或突变),就像 Youtube 上似乎发生的那样,那么该元素在该事件触发时将不存在。

我建议使用不同的方法,例如 mutation observer,而不是传统的事件侦听器。

示例:

const callback = function(mutationsList, observer) {
    for (const mutation of mutationsList) {
        if (mutation.target.id === "channel-name") {
            console.log("Element found:", document.getElementById("channel-name"));
            // disconnect the observer
            observer.disconnect();
            // element exists, run your code below
        }
    }
};
const observer = new MutationObserver(callback);
observer.observe(document.body, {childList: true, subtree: true });

上面的代码片段监视 dom 的突变,当发生具有目标为 channel-nameid 的突变时,它会执行代码。在上面的例子中,我断开了观察者的连接(你可能想也可能不想这样做)然后我记录了元素。