当页面仍在加载时,如何检测浏览器下载特定 DOM 节点的时间?
How can I detect the moment a specific DOM node has been downloaded by the browser, while the page is still loading?
我正在编写需要访问页面上特定 DOM 节点的用户脚本。为了减少延迟和页面重新布局,我想将其设置为 // @run-at document-start
而不是通常的 // @run-at document-end
,并且 运行 我的代码会在我需要的 DOM 节点时立即设置已从服务器下载。
如果我只是等待一个DOMContentLoaded
事件,它将等待整个页面被下载;这实际上与 // @run-at document-end
相同。我想 运行 我的代码在更早的时间,就在浏览器的解析器遇到我想要的元素的结束标记时。
有没有比从 MutationObserver
回调中轮询 querySelectorAll
更优雅的方法来完成此操作?
这是我目前使用的:
const element = (selector, pred = () => true, below = document) =>
new Promise((accept, reject) => {
const mo = new MutationObserver((mutations, self) => {
for (const node of below.querySelectorAll(selector)) {
if (!pred(node))
continue;
accept(node);
self.disconnect();
return;
}
}).observe(below, {
childList: true,
attributes: true,
characterData: true,
subtree: true,
});
document.addEventListener('DOMContentLoaded', ev => {
reject();
if (mo) mo.disconnect();
});
});
上面的 returns 承诺在满足我的条件的节点首次出现在 DOM 树中时解决。为了等待完全下载的那一刻,我额外将其传递给:
const nodeComplete = (node) => new Promise((accept, reject) => {
if (document.readyState === "complete" || document.readyState === "loaded") {
accept();
return;
}
document.addEventListener('DOMContentLoaded', ev => {
accept();
if (mo) mo.disconnect();
});
const mo = new MutationObserver((mutations, self) => {
let anc = node;
while (anc) {
if (anc.nextSibling) {
accept();
self.disconnect();
}
anc = anc.parentNode;
}
}).observe(document, {
childList: true,
subtree: true,
});
});
不是特别好,但可以用;我想可以在这里应用一些优化。
我正在编写需要访问页面上特定 DOM 节点的用户脚本。为了减少延迟和页面重新布局,我想将其设置为 // @run-at document-start
而不是通常的 // @run-at document-end
,并且 运行 我的代码会在我需要的 DOM 节点时立即设置已从服务器下载。
如果我只是等待一个DOMContentLoaded
事件,它将等待整个页面被下载;这实际上与 // @run-at document-end
相同。我想 运行 我的代码在更早的时间,就在浏览器的解析器遇到我想要的元素的结束标记时。
有没有比从 MutationObserver
回调中轮询 querySelectorAll
更优雅的方法来完成此操作?
这是我目前使用的:
const element = (selector, pred = () => true, below = document) =>
new Promise((accept, reject) => {
const mo = new MutationObserver((mutations, self) => {
for (const node of below.querySelectorAll(selector)) {
if (!pred(node))
continue;
accept(node);
self.disconnect();
return;
}
}).observe(below, {
childList: true,
attributes: true,
characterData: true,
subtree: true,
});
document.addEventListener('DOMContentLoaded', ev => {
reject();
if (mo) mo.disconnect();
});
});
上面的 returns 承诺在满足我的条件的节点首次出现在 DOM 树中时解决。为了等待完全下载的那一刻,我额外将其传递给:
const nodeComplete = (node) => new Promise((accept, reject) => {
if (document.readyState === "complete" || document.readyState === "loaded") {
accept();
return;
}
document.addEventListener('DOMContentLoaded', ev => {
accept();
if (mo) mo.disconnect();
});
const mo = new MutationObserver((mutations, self) => {
let anc = node;
while (anc) {
if (anc.nextSibling) {
accept();
self.disconnect();
}
anc = anc.parentNode;
}
}).observe(document, {
childList: true,
subtree: true,
});
});
不是特别好,但可以用;我想可以在这里应用一些优化。