扩展的脚本不会在 运行 之前等待整个页面加载
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
如果 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-name
的 id
的突变时,它会执行代码。在上面的例子中,我断开了观察者的连接(你可能想也可能不想这样做)然后我记录了元素。
我最近开始开发 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
如果 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-name
的 id
的突变时,它会执行代码。在上面的例子中,我断开了观察者的连接(你可能想也可能不想这样做)然后我记录了元素。