【问题标题】:Why is my MutationObserver callback not being executed for some new tags?为什么我的 MutationObserver 回调没有针对某些新标签执行?
【发布时间】:2014-09-07 14:52:08
【问题描述】:

我正在开发一个 Chrome 扩展程序,该扩展程序会影响(除其他外)页面上的 GIF 图像。我正在努力让它适用于在初始页面加载后动态添加的新图像。以下是我添加到内容脚本中以尝试处理这些内容的内容:

function processGif(newTag) {
  console.log(newTag.src);
}

var observer = new MutationObserver(function(mutations, obs) {
  for(var i=0; i<mutations.length; ++i) {
    for(var j=0; j<mutations[i].addedNodes.length; ++j) {
      var newTag = mutations[i].addedNodes[j];
      if(newTag.tagName == "IMG" && /.gif$/i.test(newTag.src)) {
        processGif(newTag);
      }
    }
  }
});

observer.observe(document.documentElement, {
  childList: true,
  subtree: true
});

出于测试目的,我将processGif 函数简化为标签的src 属性的console.log

在大多数情况下,它工作得很好,并且成功地捕获了在页面首次加载时最初构建 DOM 时创建的所有初始图像。但是在像 Google+ 这样的页面上,当您向下滚动时,MutationObserver 似乎没有捕捉到任何动态加载的帖子。我一直在使用Koushik Dutta's public page 进行测试——这家伙喜欢发布 gif。如果您尝试将上述代码粘贴到控制台并向下滚动,您应该能够确认没有检测到动态加载的图像。

为什么我看不到这些动态添加的img标签,我需要做什么来处理像这样动态添加的图像?

【问题讨论】:

    标签: javascript html google-chrome mutation-observers


    【解决方案1】:

    我想我知道发生了什么。您通过观察者获得的addedNodes 列表实际上并不是已添加到 DOM 中的每个节点的列表,而是一次添加多个节点时的最顶部的一个。

    考虑到这一点,您只需处理每个添加的节点及其所有子节点。所以需要修改观察者回调,如下所示。

    observer = new MutationObserver(function(mutations, obs) {
      for(var i=0; i<mutations.length; ++i) {
        for(var j=0; j<mutations[i].addedNodes.length; ++j) {
          var newTag = mutations[i].addedNodes[j];
          if (newTag.querySelectorAll) {
            Array.prototype.forEach.call(
              newTag.querySelectorAll('img[src*=".gif"]'),
              processGif);
          }
        }
      }
    });
    

    【讨论】:

    • 你是对的。但是,当我在加载 DOM 之前添加观察者时,我会以这种方式多次遇到相同的元素。我想知道这是否只是一个错误,或者树中的巨大变化是否会触发相同的行为。
    猜你喜欢
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    相关资源
    最近更新 更多