Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在运行脚本之前等待页面完成加载所有内容,或者如何最好地检测主要的DOM更改_Javascript_Jquery_Google Chrome_Google Chrome Extension_Google Chrome App - Fatal编程技术网

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);
});