'MutationObserver' 上的 'observe':参数 1 不是 'Node' 类型

新手上路,请多包涵

我正在创建一个 Chrome 扩展,并试图在 gMail 撰写框的发送按钮旁边包含一个小文本。

我正在使用 MutationObserver 来了解撰写框窗口何时出现。我通过观察具有类 no 的元素来执行此操作,因为撰写框元素是作为该元素(类 no )的子元素创建的。

当用户单击撰写按钮并出现撰写框窗口时,我使用 .after() 方法在发送按钮旁边放置一个元素。发送按钮类名称是 .gU.Up

这些是 gMail 的真实类名,也很奇怪。

下面是我正在使用的代码:

 var composeObserver = new MutationObserver(function(mutations){
    mutations.forEach(function(mutation){
        mutation.addedNodes.forEach(function(node){
            $(".gU.Up").after("<td> <div> Hi </div> </td>");
        });
    });
});

var composeBox = document.querySelectorAll(".no")[2];
var config = {childList: true};
composeObserver.observe(composeBox,config);

问题是我不断收到以下错误:

 Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'

谁能帮忙?我已经尝试了很多事情,也在这里查看了其他答案,但仍然无法摆脱这个错误。

这是我的 manifest.json 文件:

 {
    "manifest_version": 2,
    "name": "Gmail Extension",
    "version": "1.0",

    "browser_action": {
        "default_icon": "icon19.png",
        "default_title": "Sales Analytics Sellulose"
    },

    "background": {
        "scripts": ["eventPage.js"],
        "persistent": false
    },

    "content_scripts": [
    {
        "matches": ["https://mail.google.com/*"],
        "js": ["jquery-3.1.1.js", "insQ.min.js", "gmail_cs.js"]
    }
],

    "web_accessible_resources":[
        "compose_icon.png",
        "sellulosebar_icon.png"
    ]
}

PS 我已经尝试过 insertionquery 库,但它有一些缺点。它不会让我具体说明特定元素的变化。我还没有尝试 mutationsummary 库,但由于它使用 MutationObserver,我认为问题会持续存在。

从评论中添加:

的确,选择器没有给我一个节点。我检查了控制台,它给出了一个对象。我还检查了控制台,它正在选择我想要观察的适当元素。

但是,当我为所选元素添加 console.log 时,它显示为未定义。这意味着,关于在节点出现之前执行的代码,您可能是正确的。你能告诉我如何确保延迟发生吗? “setTimeout”会起作用吗?在 MutationObserver 的情况下它是如何工作的?

原文由 geet mehar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3k
2 个回答

正如我在评论中提到的,Xan 给出了一个答案,该错误清楚地表明 document.querySelectorAll(".no")[2] 的结果未计算为 Node

从您在评论中提供的信息来看,问题很明显是您希望观察的节点在您的代码执行时不存在。有很多方法可以延迟代码的执行,直到该节点可用。一些可能性是:

  1. 使用 setTimeout 循环进行轮询,直到检测到要放置 MutationObserver 的元素可用:
    function addObserverIfDesiredNodeAvailable() {
       var composeBox = document.querySelectorAll(".no")[2];
       if(!composeBox) {
           //The node we need does not exist yet.
           //Wait 500ms and try again
           window.setTimeout(addObserverIfDesiredNodeAvailable,500);
           return;
       }
       var config = {childList: true};
       composeObserver.observe(composeBox,config);
   }
   addObserverIfDesiredNodeAvailable();

这将在 DOM 中存在后相对较短的时间内找到合适的节点。此方法的可行性取决于插入目标节点后多长时间您需要将观察者放置在其上。显然,您可以根据需要调整轮询尝试之间的延迟。

  1. 创建另一个 MutationObserver 以监视 DOM 中较高的祖先节点,以插入要放置主要观察者的节点。虽然这会在插入时立即找到合适的节点,但它可能会占用大量资源 (CPU),具体取决于您必须观察的 DOM 的高度以及与 DOM 更改相关的活动量。

原文由 Makyen 发布,翻译遵循 CC BY-SA 3.0 许可协议

尝试将其与 jQuery 一起使用。

如果您正在开发 Chrome 扩展,并且您正在从页面或 content_script 中的 DOM 获取 HTML 元素(节点),那么您将获得对象,并且节点将作为对象的属性返回。然后,您可以从对象中获取节点以传递给 observe(Node,config) 方法。

例子

var node = $("#elementId");  //this is wrong because if you logged this in the console you will get Object

var node = $("#elementId")[0];  //This gives the first property of the Object returned, and this is correct because if you logged this in the console you will get the Node element for which you want to detect changes in the DOM.

原文由 Code Me 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题