简体   繁体   English

“MutationObserver”上的“观察”:参数 1 不是“节点”类型

[英]'observe' on 'MutationObserver': parameter 1 is not of type 'Node'

I am creating a Chrome extension and trying to include a small text beside the SEND button of the gMail compose box.我正在创建一个 Chrome 扩展程序并尝试在 gMail 撰写框的发送按钮旁边包含一个小文本。

I am using a MutationObserver to know when the compose box window appears.我正在使用 MutationObserver 来了解撰写框窗口何时出现。 I am doing this by observing an element with class no since the compose box element is created as child of this element (class no ).我是通过观察类no的元素来做到这一点的,因为 compose box 元素是作为该元素(类no )的子元素创建的。

When the user clicks on the compose button and the compose box window appears, then I place an element beside the SEND button using the .after() method.当用户单击撰写按钮并出现撰写框窗口时,我会使用.after()方法在 SEND 按钮旁边放置一个元素。 SEND button class name is .gU.Up . SEND 按钮类名称是.gU.Up

These are the real class names of gMail and pretty weird too.这些是 gMail 的真实类名,而且也很奇怪。

Below is the code I am using:下面是我正在使用的代码:

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

The problem is that I constantly get following error:问题是我不断收到以下错误:

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

Can anyone help?任何人都可以帮忙吗? I have tried quite a few things and also looked at other answers here, but still am unable to get rid of this error.我已经尝试了很多东西,也在这里查看了其他答案,但仍然无法摆脱这个错误。

Here is my manifest.json file:这是我的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 I have already tried the insertionquery library, but it has a few shortcomings. PS 我已经尝试过插入查询库,但它有一些缺点。 It doesn't let me be specific as to the changes in the specific element.它不允许我具体说明特定元素的变化。 I am yet to try the mutationsummary library, but since it uses MutationObserver, I figured the issue will persist.我还没有尝试过 mutationsummary 库,但由于它使用了 MutationObserver,我认为这个问题会持续存在。

Added from comment:从评论中添加:
It is true that the selector is not giving me a node.确实,选择器没有给我一个节点。 I checked in the console, it's giving a object.我检查了控制台,它给出了一个对象。 I also checked in the console and it's selecting the appropriate element that I want to be observed.我还检查了控制台,它正在选择我想要观察的适当元素。

However, when I add console.log for the element selected, it's showing as undefined.但是,当我为所选元素添加console.log时,它显示为未定义。 Which means, you are probably right about code executing prior to nodes coming into existence.这意味着,在节点出现之前执行代码可能是正确的。 Can you tell me how to make sure the delay happens?你能告诉我如何确保延迟发生吗? will 'setTimeout' work? “setTimeout”会起作用吗? How does it work in case of MutationObserver?在 MutationObserver 的情况下它是如何工作的?

As I mentioned in a comment, and Xan stated an answer, the error makes it clear that the result of document.querySelectorAll(".no")[2] does not evaluate to a Node .正如我在评论中提到的,Xan 给出了一个答案,该错误清楚地表明document.querySelectorAll(".no")[2]未计算为Node

From the information you provided in a comment, it is clear that the issue is that the node you desire to observe does not exist when your code executes.从您在评论中提供的信息来看,问题很明显是您希望观察的节点在您的代码执行时不存在。 There are many ways to delay the execution of your code until that node is available.有很多方法可以延迟代码的执行,直到该节点可用。 Some possibilities are:一些可能性是:

  1. Using a setTimeout loop to poll until you detect that the element on which you want to put the MutationObserver is available:使用 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();

    This will find the appropriate node relatively shortly after it exists in the DOM.这将在 DOM 中存在后相对较短的时间内找到合适的节点。 The viability of this method depends on how long after the insertion of the target node do you need the observer to be placed on it.这种方法的可行性取决于插入目标节点后多久需要将观察者放置在其上。 Obviously, you can adjust the delay between polling attempts based on your needs.显然,您可以根据需要调整轮询尝试之间的延迟。

  2. Create another MutationObserver to watch an ancestor node higher in the DOM for the insertion of the node on which you want to place your primary observer.创建另一个 MutationObserver 以观察 DOM 中更高的祖先节点,以插入要放置主要观察者的节点。 While this will find the appropriate node immediately when it is inserted, it may be quite resource (CPU) intensive, depending on how high in the DOM you have to observe and how much activity there is with respect to DOM changes.虽然这会在插入时立即找到合适的节点,但它可能会占用大量资源 (CPU),具体取决于您必须观察的 DOM 的高度以及与 DOM 更改相关的活动量。

Try to use this with jQuery.尝试在 jQuery 中使用它。

If you are developing a Chrome Extension and you are getting HTML element(Node) from the page or DOM in the content_script , then you will get Object and Node will be returned as property of the Object.如果您正在开发 Chrome 扩展程序并且您正在从页面或content_script 中的DOM 获取 HTML 元素(节点),那么您将获得 Object 并且 Node 将作为 Object 的属性返回。 You can then get Node from the Object to pass into observe(Node,config) method.然后,您可以从对象中获取 Node 以传递给observe(Node,config)方法。

Example示例

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.

This error means that document.querySelectorAll(".no")[2] is not a Node .此错误意味着document.querySelectorAll(".no")[2]不是Node

Most likely this means there isn't such an element;这很可能意味着没有这样的元素; querySelectorAll will always return a NodeList , even if it's empty; querySelectorAll将始终返回一个NodeList ,即使它是空的; accessing non-existent members of the list succeeds without a runtime error, but returns undefined : in this sense, NodeList acts like an array.访问不存在的列表成员会成功而不会出现运行时错误,但会返回undefined :从这个意义上说, NodeList就像一个数组。

"Wait, but it does! I run this code in the console and it works!" “等等,但它确实如此!我在控制台中运行了这段代码,它工作正常!” you may exclaim dramatically.你可能会惊呼。 That's because at the time you execute it, long after the document finishes loading, those elements exist.那是因为在您执行它时,在文档完成加载很久之后,这些元素就存在了。

So, you need to wait for this root element to be added;所以,你需要等待这个根元素被添加; likely, with another MutationObserver to do the job.很可能,用另一个MutationObserver来完成这项工作。

I am creating a Chrome extension and trying to include a small text beside the SEND button of the gMail compose box.我正在创建一个 Chrome 扩展程序并尝试在 gMail 撰写框的发送按钮旁边包含一个小文本。

I am using a MutationObserver to know when the compose box window appears.我正在使用 MutationObserver 来了解撰写框窗口何时出现。 I am doing this by observing an element with class no since the compose box element is created as child of this element (class no ).我是通过观察类no的元素来做到这一点的,因为 compose box 元素是作为该元素(类no )的子元素创建的。

When the user clicks on the compose button and the compose box window appears, then I place an element beside the SEND button using the .after() method.当用户单击撰写按钮并出现撰写框窗口时,我会使用.after()方法在 SEND 按钮旁边放置一个元素。 SEND button class name is .gU.Up . SEND 按钮类名称是.gU.Up

These are the real class names of gMail and pretty weird too.这些是 gMail 的真实类名,也很奇怪。

Below is the code I am using:下面是我正在使用的代码:

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

The problem is that I constantly get following error:问题是我不断收到以下错误:

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

Can anyone help?任何人都可以帮忙吗? I have tried quite a few things and also looked at other answers here, but still am unable to get rid of this error.我已经尝试了很多东西,也在这里查看了其他答案,但仍然无法摆脱这个错误。

Here is my manifest.json file:这是我的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 I have already tried the insertionquery library, but it has a few shortcomings. PS 我已经尝试过插入查询库,但它有一些缺点。 It doesn't let me be specific as to the changes in the specific element.它不允许我具体说明特定元素的变化。 I am yet to try the mutationsummary library, but since it uses MutationObserver, I figured the issue will persist.我还没有尝试过 mutationsummary 库,但由于它使用了 MutationObserver,我认为这个问题会持续存在。

Added from comment:从评论中添加:
It is true that the selector is not giving me a node.确实,选择器没有给我一个节点。 I checked in the console, it's giving a object.我检查了控制台,它给出了一个对象。 I also checked in the console and it's selecting the appropriate element that I want to be observed.我还检查了控制台,它正在选择我想要观察的适当元素。

However, when I add console.log for the element selected, it's showing as undefined.但是,当我为所选元素添加console.log时,它显示为未定义。 Which means, you are probably right about code executing prior to nodes coming into existence.这意味着,在节点出现之前执行代码可能是正确的。 Can you tell me how to make sure the delay happens?你能告诉我如何确保延迟发生吗? will 'setTimeout' work? “setTimeout”会起作用吗? How does it work in case of MutationObserver?在 MutationObserver 的情况下它是如何工作的?

如果你使用jQuery,把这段代码放在

$(document).ready(function(){ // your code });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法在“MutationObserver”上执行“观察”:参数 1 不是“节点”类型 - Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node' 未捕获的类型错误:无法在“MutationObserver”上执行“观察”:参数 1 的类型不是“节点” - Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node' 无法在“MutationObserver”上执行“观察”:参数 1 不是“节点”类型。 选择2() - Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'. select2() 我收到“未捕获的类型错误:无法在‘MutationObserver’上执行‘观察’:参数 1 不是‘节点’类型。” - I am getting "Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'." 使用 MutationObserver 时“参数 1 不是‘节点’类型” - "parameter 1 is not of type 'Node'" when using MutationObserver MutationObserver - 得到“TypeError: MutationObserver.observe: Argument 1 does not implement interface Node.” - MutationObserver - getting “TypeError: MutationObserver.observe: Argument 1 does not implement interface Node.” MutationObserver 只观察一次 - MutationObserver observe only once MutationObserver无法观察textarea - MutationObserver fails to observe textarea MutationObserver观察jquery追加? - MutationObserver observe jquery append? 无法在“IntersectionObserver”上执行“observe”:参数 1 不是“元素”类型 - Failed to execute 'observe' on 'IntersectionObserver': parameter 1 is not of type 'Element'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM