【问题标题】:Javascript loop through DOM elements is unreliable for async scripts通过 DOM 元素的 Javascript 循环对于异步脚本是不可靠的
【发布时间】:2020-09-08 04:37:09
【问题描述】:

我正在尝试在来自 Google chrome 扩展的内容脚本中循环浏览网页的 DOM 元素。问题是结果列表有时会有所不同,我怀疑这是因为脚本标记为异步,但由于进程应该以 window.onload 开头,这对我来说没有任何意义。有谁明白为什么会发生这种情况? 编辑 :: 我开始认为这可能是因为我将 window.onload 函数标记为异步。那会是问题吗?

javascript代码如下。它为脚本添加了“2”,为 iframe 添加了“1”,为其他添加了“-1”(稍后将忽略“-1”)。

async function exam(element){
        if (element.nodeName == 'SCRIPT'){
                return '2';
        }else if (element.nodeName == 'IFRAME'){
                return '1';
        }else{
                return '-1';
        }
}

async function domExam(element, list) {
        let res = await exam(element);
        if(res != '-1'){
            list.push(res);
        }
        let chNodes = element.children;
        if (chNodes.length > 0 ){
            for (let item of chNodes){
                list = await domExam(item, list);
            }
            return list;
        }else{
            return list;
        }
}

window.onload = async function(){
    list = await domExam(document, []);
    console.log("List::", list);
}  

【问题讨论】:

    标签: javascript dom google-chrome-extension async-await onload


    【解决方案1】:

    onload 事件的处理是它可能会在一个或多个脚本执行之前触发。

    页面中可能有一些其他脚本正在异步执行或加载,AFAIK 无法知道何时执行某些第三方脚本并以某种方式更改 DOM。您必须假设 DOM 是并且将始终是可变的并以这种方式使用它。

    【讨论】:

    • 感谢您的回答。在许多地方,据说 window.onload 应该在所有内容加载后触发,例如图片。您确定异步 javascript 包含不受此限制吗? stackoverflow.com/questions/40193553/…
    • 是的,你永远不知道异步加载或异步执行的 JS 何时完成加载或执行。这就是你需要回调的原因。
    • window.onload 在异步脚本加载之前不会触发。异步脚本不会阻塞解析,它们可以在文档 DOMContentLoaded 之前和之后以任何顺序执行,但在 onload 之前执行
    【解决方案2】:

    正如在另一个答案中所说,由于页面中的其他 javascript,DOM 可能随时更改

    您可以使用 MutationObserver 来跟踪任何更改,并针对新的 DOM 再次运行您的函数(我建议取消此操作,因为某些脚本可能会进行许多小的更改)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多