"watch" on "MutationObserver": parameter 1 is not of type "Node"

I am creating a Chrome extension and am trying to include a little text next to the SEND button in the gMail layout field.

I use MutationObserver to find out when the layout window appears. I do this by observing an element with class no , since the layout box element is created as a child of this element (class no ).

When the user clicks the layout button and the layout window window appears, I place the item next to the SEND button using the .after() method. The button class name is SEND .gU.Up .

These are real gMail class names and are pretty weird too.

The following is the code I'm 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 the following error:

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

Can anyone help? I tried a lot of things and also looked at other answers here, but still can not get rid of this error.

Here is my manifest.json file:

 { "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 several drawbacks. This does not allow me to be specific regarding changes in a particular element. I have yet to try the mutationsummary library, but since it uses MutationObserver, I decided that the problem would persist.

Added from comment:
It is true that the selector does not give me node. I checked in the console giving the object. I also checked in the console and selected the corresponding item that I want to observe.

However, when I add console.log for the selected item, it appears as undefined. This means that you are probably right in executing the code before nodes appear. Can you tell me how to make a delay happen? will setTimeout work? How does this work in the case of MutationObserver?

+7
javascript google-chrome-extension gmail mutation-observers gmail-api
source share
3 answers

As I mentioned in the comment, and Xan answered the answer, the error makes it clear that the result of document.querySelectorAll(".no")[2] not evaluated by Node .

From the information you provided in the comment, it’s clear that the problem is that the node you want to watch does not exist when your code executes. There are many ways to delay code execution until a node is available. Some features:

  • Use the setTimeout loop to poll until you find that the element in which you want to put MutationObserver is available :

     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 a suitable node relatively soon after its existence in the DOM. The viability of this method depends on how long after inserting the node target you need an observer to be placed on it. Obviously, you can adjust the delay between polling attempts based on your needs.

  • Create another MutationObserver to watch the node ancestor above in the DOM to insert the node on which you want to place your main observer. Although it will immediately find the corresponding node when it is inserted, it can be quite resource intensive (CPU) intensive, depending on how high in the DOM you should be observing and what kind of activity exists regarding DOM changes.
+5
source share

This error means that document.querySelectorAll(".no")[2] not a Node .

Most likely, this means that there is no such element; querySelectorAll will always return a NodeList , even if it is empty; access to nonexistent list members is performed without errors at runtime, but returns undefined : in this sense, a NodeList acts like an array.

"Wait, but it is! I run this code in the console and it works!" you can object sharply. This is because at the time you execute it, after the document finishes loading, these elements exist.

So, you need to wait for the addition of this root element; probably with another MutationObserver to do the job.

+3
source share

If you are using jQuery, put this code in

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

All Articles