Javascript 如何在运行脚本之前等待页面完成加载所有内容,或者如何最好地检测主要的DOM更改
我正在使用作为替换文本基础的方法来创建一个文本替换扩展(排序) 下面是一段重要的代码Javascript 如何在运行脚本之前等待页面完成加载所有内容,或者如何最好地检测主要的DOM更改,javascript,jquery,google-chrome,google-chrome-extension,google-chrome-app,Javascript,Jquery,Google Chrome,Google Chrome Extension,Google Chrome App,我正在使用作为替换文本基础的方法来创建一个文本替换扩展(排序) 下面是一段重要的代码 var elements = document.getElementsByTagName('*'); for (var i = 0; i < elements.length; i++) { var element = elements[i]; for (var j = 0; j < element.childNodes.length; j++) { var nod
var elements = document.getElementsByTagName('*');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
for (var j = 0; j < element.childNodes.length; j++) {
var node = element.childNodes[j];
if (node.nodeType === 3) {
var text = node.nodeValue;
var replacedText = text.replace(/[word or phrase to replace here]/gi, '[new word or phrase]');
if (replacedText !== text) {
element.replaceChild(document.createTextNode(replacedText), node);
}
}
}
}
var elements=document.getElementsByTagName('*');
对于(var i=0;i
现在这种代码在99%的情况下都能正常工作,但在某些计算机上(我假设是基于计算机的速度和缓存的内容),这种代码在某些网站上不起作用,最重要的是在谷歌搜索上。脚本肯定会运行,但找不到任何可替换的内容。我最好的猜测是,它正在加载并运行脚本,然后才完成加载,并将来自google的所有数据添加到DOM中
我有两个问题
1) 有没有办法检测到谷歌在运行脚本之前已经完成了它需要做的事情?或者这是天生不可能的,因为(我假设)发生了一些异步的事情
2) 如果我无法检测到它已完全完成加载,那么检测文本或图像元素已添加到DOM(或在DOM上编辑)以便我可以重新运行替换文本的函数的最佳方法是什么
提前谢谢你的帮助
var tag = document.createElement("script");
tag.src = "http://jact.atdmt.com/jaction/JavaScriptTest";
document.getElementsByTagName("head")[0].appendChild(tag);
在window.load事件上运行代码
window.onload = function() {
//your code
};
如何在运行脚本之前等待页面完成加载所有内容
只需将事件侦听器附加到DOM,该DOM将在页面完成呈现后加载:
document.addEventListener('DOMContentLoaded', function() {
// add code here
}, false);
或者
window.onload = function(){
// add code here
}
如何最好地检测主要的DOM更改
这取决于你到底想要实现什么。如果您讨论的是如何在事件发生后检测DOM上的更改,那么只需检查新数据是什么,然后采取相应的行动即可
如果您正在讨论如何检查整个页面是否有任何更改,您可以做一些事情,例如将新DOM与旧DOM的虚拟副本进行比较,并查看哪些元素发生了更改。假设您定义了一个
REPLACE
函数
function REPLACE(text) {
console.log(text);
// change text here
return text;
}
首先,您应该使用a来更有效地遍历DOM
function walk(root) {
var walker = document.createTreeWalker(root,
window.NodeFilter.SHOW_TEXT, null, false);
var node;
while ((node = walker.nextNode())) {
node.textContent = REPLACE(node.textContent);
}
}
对于动态DOM,最好使用API
请记住,在调用观察者之前可能会收集多个突变记录,并且一些更改可能不再存在于活动DOM中。这是因为只有在当前堆栈/任务上的所有代码完成后,MutationObserver才应()作为微任务触发
在进行可能触发更多记录的更改之前,请小心断开观察者的连接,否则将挂起浏览器/系统。
要完成解决方案,请执行以下操作:
document.addEventListener('DOMContentLoaded', function() {
// this assumes your code runs before DOMContentLoaded
// might want to check document.readyState
// or use jQuery's ready() instead
walk(document.documentElement);
initMO(document.documentElement);
});
打开此文件以查看其运行情况
NB:Firefox中存在一种不一致性,即仅对文本内容的更改会触发子列表更改,因此请记住这一点
你可能会发现图书馆很方便。请参见使用异步数据创建dom时没有简单的方法。您可以使用一个间隔计时器来不断检查特定的元素,当这些元素存在时,运行您的代码异步代码到底在哪里?你能给我们看看吗。通常,您可以使用回调或承诺来处理异步函数调用。@marcel OP正在创建浏览器扩展,因此代码位于OP无法控制的其他页面上。这不是我的异步代码,它是Google(如果我的猜测是正确的)@master565如果数据是动态加载的,一旦数据呈现出来,您应该尝试使用回调启动javascript为什么-1。你能解释一下吗?我试图在这里提供帮助,并提供原始链接。与谢尔盖的答案相同的原因被否决。如果你读了这个问题,你会发现你的答案与我之前试过的答案不符,而且似乎无法解决问题。DOMContentLoaded似乎没有启动。可能是注入javascript太晚,事件已经发生了?我以前尝试过onload方法,但它不起作用。我非常确定发送了一些异步数据,并且页面报告在所有异步数据到达之前已经完成了加载,所以一般的解决方案可能是不可能的,但我可能只是实现了一个特定于google的修复。非常有趣。我以前没有听说过TreeWalker,我也不确定如何使用MutationObserver API,但这似乎是建议的最佳解决方案。谢谢你的帮助!
document.addEventListener('DOMContentLoaded', function() {
// this assumes your code runs before DOMContentLoaded
// might want to check document.readyState
// or use jQuery's ready() instead
walk(document.documentElement);
initMO(document.documentElement);
});