当Chrome扩展插入元素时,Mutation Observer不起作用

时间:2016-06-12 16:48:00

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

当我双击某个单词时谷歌翻译的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),但不适用于Google Translate插入的翻译div!谁知道我做错了什么?

2 个答案:

答案 0 :(得分:0)

那是因为您要查找的节点#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,因此不需要递归地观察页面,这自然比观察仅一个节点的子列表慢。

答案 1 :(得分:0)

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