'observe' on 'MutationObserver': 参数 1 不是 'Node' 类型
'observe' on 'MutationObserver': parameter 1 is not of type 'Node'
我正在创建一个 Chrome 扩展并尝试在 gMail 撰写框的“发送”按钮旁边包含一个小文本。
我正在使用 MutationObserver 来了解撰写框 window 何时出现。我通过观察带有 class no
的元素来执行此操作,因为撰写框元素是作为该元素 (class no
).
的子元素创建的
当用户单击撰写按钮并出现撰写框 window 时,我使用 .after()
方法在发送按钮旁边放置了一个元素。发送按钮 class 名称是 .gU.Up
。
这些是 gMail 的真实 class 名称,也很奇怪。
下面是我使用的代码:
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"
]
}
P.S。我已经尝试过 insertionquery 库,但它有一些缺点。它不会让我具体说明特定元素的变化。我还没有尝试 mutationsummary 库,但由于它使用了 MutationObserver,我认为这个问题会持续存在。
添加自评论:
的确,选择器没有给我一个节点。我检查了控制台,它给出了一个对象。我还检查了控制台,它正在选择我想要观察的适当元素。
但是,当我为所选元素添加 console.log
时,它显示为未定义。这意味着,关于在节点出现之前执行的代码,您可能是正确的。你能告诉我如何确保延迟发生吗? 'setTimeout' 有用吗?在 MutationObserver 的情况下它是如何工作的?
此错误表示 document.querySelectorAll(".no")[2]
不是 Node
。
很可能这意味着没有这样的元素; querySelectorAll
将始终 return 一个 NodeList
,即使它是空的;访问列表中不存在的成员会成功,不会出现运行时错误,但是 returns undefined
:在这个意义上,NodeList
就像一个数组。
"Wait, but it does! I run this code in the console and it works!"你可能会惊呼。那是因为在您执行它时,在文档完成加载很久之后,那些元素就存在了。
因此,您需要等待添加此根元素;可能,与另一个 MutationObserver
一起完成这项工作。
正如我在评论中提到的,Xan 给出了一个答案,该错误清楚地表明 document.querySelectorAll(".no")[2]
的结果未计算为 Node。
从您在评论中提供的信息来看,问题很明显是您的代码执行时您要观察的节点不存在。有很多方法可以延迟代码的执行,直到该节点可用。一些可能性是:
使用 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 中存在后不久找到合适的节点。此方法的可行性取决于插入目标节点后多长时间您需要将观察者放置在其上。显然,您可以根据需要调整轮询尝试之间的延迟。
- 创建另一个 MutationObserver 以监视 DOM 中更高的祖先节点,以插入要放置主要观察者的节点。虽然这会在插入时立即找到合适的节点,但它可能会占用大量资源 (CPU),具体取决于您必须观察的 DOM 的高度以及 activity 的数量有关于 DOM 的变化。
如果您使用jQuery,请将此代码放入
$(document).ready(function(){ // your code });
尝试将此与 jQuery 一起使用。
如果您正在开发 Chrome 扩展,并且您正在从页面获取 HTML 元素(节点)或 content_script 中的 DOM,那么您将获得对象和节点将作为对象的 属性 返回。然后,您可以从对象中获取节点以传递给 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.
我正在创建一个 Chrome 扩展并尝试在 gMail 撰写框的“发送”按钮旁边包含一个小文本。
我正在使用 MutationObserver 来了解撰写框 window 何时出现。我通过观察带有 class no
的元素来执行此操作,因为撰写框元素是作为该元素 (class no
).
当用户单击撰写按钮并出现撰写框 window 时,我使用 .after()
方法在发送按钮旁边放置了一个元素。发送按钮 class 名称是 .gU.Up
。
这些是 gMail 的真实 class 名称,也很奇怪。
下面是我使用的代码:
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"
]
}
P.S。我已经尝试过 insertionquery 库,但它有一些缺点。它不会让我具体说明特定元素的变化。我还没有尝试 mutationsummary 库,但由于它使用了 MutationObserver,我认为这个问题会持续存在。
添加自评论:
的确,选择器没有给我一个节点。我检查了控制台,它给出了一个对象。我还检查了控制台,它正在选择我想要观察的适当元素。
但是,当我为所选元素添加 console.log
时,它显示为未定义。这意味着,关于在节点出现之前执行的代码,您可能是正确的。你能告诉我如何确保延迟发生吗? 'setTimeout' 有用吗?在 MutationObserver 的情况下它是如何工作的?
此错误表示 document.querySelectorAll(".no")[2]
不是 Node
。
很可能这意味着没有这样的元素; querySelectorAll
将始终 return 一个 NodeList
,即使它是空的;访问列表中不存在的成员会成功,不会出现运行时错误,但是 returns undefined
:在这个意义上,NodeList
就像一个数组。
"Wait, but it does! I run this code in the console and it works!"你可能会惊呼。那是因为在您执行它时,在文档完成加载很久之后,那些元素就存在了。
因此,您需要等待添加此根元素;可能,与另一个 MutationObserver
一起完成这项工作。
正如我在评论中提到的,Xan 给出了一个答案,该错误清楚地表明 document.querySelectorAll(".no")[2]
的结果未计算为 Node。
从您在评论中提供的信息来看,问题很明显是您的代码执行时您要观察的节点不存在。有很多方法可以延迟代码的执行,直到该节点可用。一些可能性是:
使用 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 中存在后不久找到合适的节点。此方法的可行性取决于插入目标节点后多长时间您需要将观察者放置在其上。显然,您可以根据需要调整轮询尝试之间的延迟。
- 创建另一个 MutationObserver 以监视 DOM 中更高的祖先节点,以插入要放置主要观察者的节点。虽然这会在插入时立即找到合适的节点,但它可能会占用大量资源 (CPU),具体取决于您必须观察的 DOM 的高度以及 activity 的数量有关于 DOM 的变化。
如果您使用jQuery,请将此代码放入
$(document).ready(function(){ // your code });
尝试将此与 jQuery 一起使用。
如果您正在开发 Chrome 扩展,并且您正在从页面获取 HTML 元素(节点)或 content_script 中的 DOM,那么您将获得对象和节点将作为对象的 属性 返回。然后,您可以从对象中获取节点以传递给 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.