【问题标题】:Mutation Observer does not work when a Chrome Extension inserts an element当 Chrome 扩展程序插入元素时,Mutation Observer 不起作用
【发布时间】:2016-06-12 16:48:00
【问题描述】:

我正在尝试聆听 Google 翻译的 Chrome 扩展程序在您双击某个单词时插入气泡的情况,以便我可以随时将选择更改为拉丁语。

window.latinAlways = function() {
  // Google Translate Select Element
  //var gtse = document.querySelector('#gtx-host').shadowRoot.querySelector('.gtx-lang-selector');

  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      console.log(mutation.type);
      if (mutation.type == 'childList') {
        if (mutation.addedNodes.length >= 1) {
          mutation.addedNodes.forEach(function(node) {
            if (node.id == 'gtx-host') {
              // Google Translate Select Element
              var gtse = document.querySelector('#gtx-host').shadowRoot.querySelector('.gtx-lang-selector');
              for (var i = 0; i < gtse.length; i++) {
                if (gtse.children[i].textContent == "Latin") {
                  gtse.options.selectedIndex = i;
                  break;
                }
              }
            }
          });
        }
      }
    });
  });

  // Notify me of everything!
  var observerConfig = {
    childList: true,
    subtree: true
  };

  // Node, config
  // In this case we'll listen to all changes to body and child nodes
  var targetNode = document.body;
  observer.observe(targetNode, observerConfig);
};
window.latinAlways();

问题是,代码适用于通常的 document.body.appendChild(el),但不适用于谷歌翻译插入的翻译 div!有谁知道我做错了什么?

【问题讨论】:

  • 感谢您发布此信息。对我帮助很大。

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


【解决方案1】:

wOxxOm 的回答通常内容丰富,但不正确。

Div #gtx-host IS 作为单独的突变添加。为什么不呢?

我不知道为什么 TS 认为他的代码不起作用。下面是我的代码(部分取自 wOxxOm 答案,部分取自问题),它是有效的(至少它将选定的选项更改为拉丁语)。

var observer = new MutationObserver(function(mutations) {
label:
for (var i = mutations.length - 1; i >= 0; i--) {
    var m = mutations[i];
    var nodes = m.addedNodes;
    for (var j = nodes.length - 1; j >= 0; j--) {
        var n = nodes[j];
        if (n.id === "gtx-host") {
            var gtse = document.querySelector('#gtx-host').shadowRoot.querySelector('.gtx-lang-selector');
            for (var i = 0; i < gtse.length; i++) {
            if (gtse.children[i].textContent == "Latin") {
              gtse.options.selectedIndex = i;
              break;
            }
          }
        }
     }
   }
 });

  var config = {
     childList : true,
     subtree : true
  };

observer.observe(target, config);

【讨论】:

    【解决方案2】:

    这是因为您要查找的节点 #gtx-host 没有作为单独的突变添加,因此 MutationRecord 仅包含外部容器 div。您可以通过在调试器中设置断点或记录来轻松查看它,例如console.log(mutations),在这种情况下应该始终是第一件事。

    只需寻找外层 div:

    var observer = new MutationObserver(function(mutations) {
        for (var i = mutations.length-1; i>=0; i--) {
            var m = mutations[i];
            var nodes = m.addedNodes;
            for (var j = nodes.length-1; j>=0; j--) {
                var n = nodes[j];
                if (n.className === "jfk-bubble gtx-bubble") {
                    .......................
                    .......................
                }
            }
        }
    });
    
    observer.observe(document.body, {childList:true});
    

    注意事项:

    1. 由于 MutationObserver 是作为 microtask 执行的,它应该非常快,以免阻塞页面上的其他 javascript,所以通常你不应该使用带有回调的数组函数,因为它们比复杂页面上的简单循环慢得多产生数千个突变。
    2. 气泡总是添加到document.body,因此不需要递归地观察页面,这自然比只观察一个节点的子列表要慢。

    【讨论】:

      猜你喜欢
      • 2012-06-03
      • 2014-06-01
      • 2012-10-27
      • 1970-01-01
      • 2015-01-16
      • 2020-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多