【问题标题】:Chrome Extension: Waiting For Element to Load (async js)Chrome 扩展:等待元素加载(异步 js)
【发布时间】:2016-04-21 04:31:52
【问题描述】:

我有一个 Chrome 扩展程序,我想等到元素加载完毕后再将内容注入页面。

我正在尝试注入一个按钮:

myButton = document.createElement('button');
myButton.class = 'mybutton';
document.querySelector('.element_id').appendChild(myButton)

我在内容脚本的顶部有这个。它曾经工作得很好,但后来它停止工作了。显示的错误是:

Uncaught TypeError: Cannot read property 'appendChild' of null

为了等待类 id .element_id 的元素加载,我尝试使用 MutationObserver

var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (!mutation.addedNodes) return

        for (var i = 0; i < mutation.addedNodes.length; i++) {
            if (mutation.addedNodes[i].parentNode == document.querySelector('#outer-container')) {

                myButton = document.createElement('button');
                myButton.class = 'mybutton';
                document.querySelector('.element_id').appendChild(myButton)
        }
            var node = mutation.addedNodes[i]
        }
    })
})

observer.observe(document.body, {
    childList: true
    , subtree: true
    , attributes: false
    , characterData: false
})

当我使用突变观察器时,页面会加载一个名为outer-container的外部div元素,我无法直接比较类.element_id.element_id 类在外部 div 中嵌套了许多层。

但是,上述方法不起作用,我仍然收到 null 属性错误。

有没有更好的方法在注入之前等待某些元素被加载(异步加载)?

【问题讨论】:

    标签: javascript google-chrome-extension mutation-observers


    【解决方案1】:

    观察变化时不要忘记添加childListsubtree属性。

    var observer = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            if (!mutation.addedNodes) {
                return;
            }
            for (var i = 0; i < mutation.addedNodes.length; i++) {
                if (mutation.addedNodes[i].classList.contains("element_id")) {
                    // Your logic here
                }
            }
        });
    });
    
    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
    

    【讨论】:

    • 对不起,我忘了包括属性。我有childList,但它仍然失败:(
    • @confused,你能试试我的代码吗?我已经验证,我相信它应该可以工作。
    • @HibaraAi 看看我的回答。
    • 另外,别忘了subtree: true
    【解决方案2】:

    对 DOM 的插入可能会使相关元素在添加的节点中更深。

    例如,这可以插入到 DOM 中:

    <div class="container">
      <div class="element_id">...</div>
      ...
    </div>
    

    在这种情况下,添加的节点列表将只包含.container 节点。

    突变不会列出添加的所有内容,您有责任通过添加节点递归地挖掘添加的片段。

    使用mutation-summary library 可以帮助您避免这样的麻烦。

    var observer = new MutationSummary({
      rootNode: document.body,
      callback: function(summaries) {
        summaries.forEach(function(summary) {
          summary.added.forEach(function(idElement) {
            /* ... */
            idElement.appendChild(myButton);
          });
        });
      },
      queries: [{element: ".element_id"}]
    });
    

    如果您不想使用库,可以尝试在addedNodes[i] 上调用querySelectorquerySelectorAll

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2021-10-08
      • 2013-11-12
      • 2016-03-16
      • 1970-01-01
      相关资源
      最近更新 更多