这个问题已经在这里有一个答案:
我试图做出的Greasemonkey脚本,在Facebook页面添加一个按钮。但我需要等待创作元素的添加就可以了按钮。
我试图用MutationObserver
(As suggested here)做,但有错误。
function init() {
console.log('Launched : ' + launched);
if (!launched) {
launched = true;
main();
}
}
console.log('barfoo');
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (!mutation.addedNodes) return;
console.log(mutation.addedNodes.type());
for (var i = 0; i < mutation.addedNodes.length; i++) {
if (mutation.addedNodes[i].matches('div[class="pam _5shk uiBoxWhite bottomborder"]')) {
console.log('init');
init();
}
}
})
});
console.log('bar');
try {
observer.observe(document.body, {
childlist: true,
subtree: true,
attributes: false,
characterData: false,
});
} catch (error) {
console.log(error);
}
console.log('foobar');
但我得到了以下日志:
barfoo
bar
DOMException [TypeError: "The expression cannot be converted to return the specified type."
code: 0
nsresult: 0x805b0034
location: file:///home/vmonteco/.mozilla/firefox/f3xgmo8e.default/gm_scripts/Facebook_cleaner/Facebook_cleaner.user.js:230] Facebook_cleaner.user.js:239:3
foobar
这是什么错误的原因是什么?我怎么能解决这个问题?
如果该元素是我的脚本执行前创建的,将MutationObserver
仍然被触发? (即,如果该元件已经当我创建MutationObserver存在)。
注:我试图用$(document).ready()
,但它创造我想要添加的按钮元素之前触发。
注二:我没有张贴整个脚本。
该错误信息使用完全模糊的不幸,但你有一个错字:
observer.observe(document.body, {
childlist: true,
subtree: true,
attributes: false,
characterData: false,
});
应该
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: false,
characterData: false,
});
例如childlist
=> childList
在这种情况下,在Chrome中运行的相同的代码提供了一个更有帮助的消息不是“不能转换返回指定的类型”。它说
选项对象必须设置的“属性”,“characterData”至少一个,或“的childList”为真。
其实,MutationObserver
是不是要做到这一点的最佳方式(如你正在学习的艰辛的道路。它很快变得复杂和脆弱。它真的可以拖垮一个网页,这不是跨平台的一致性)。
另外,如果你的元素脚本火灾之前就存在,MutationObserver不会赶上它。
使用像如图Run Greasemonkey script on the same page, multiple times?的方法。
就这样,你的整个脚本变为:
// ==UserScript==
// @name _Wait for specific divs
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
waitForKeyElements (
'div.pam _5shk.uiBoxWhite.bottomborder', processDiv
);
function processDiv (jNode) {
// YOUR CODE HERE.
// For example:
jNode.css ("background", "pink");
}
看得出来是多么容易! :)
随着waitForKeyElements()
您可以根据需要使用任何复杂的jQuery选择。
如果你真的坚持MutationObserver
s,使用花费的痛苦了它的库。
This answer shows how to use MutationObserver in a Greasemonkey/Tampermonkey script.
我看到一种意见认为MutationObserver不是办法做到这一点,但实际上,它是。细微差别是,如果你要处理的是加载从一开始就正确,页面的节点,然后不会错过任何东西,你必须运行与// @run-at document-start
条件猴脚本,然后例如附加观察者到document.documentElement
赶上绝对一切(或者,如果你确信nonthing将在页面以后更改会破坏这个稍后出现的元素):
(function()
{
new MutationObserver((mutationsList, observer) => {
for (let mutation of mutationsList)
{
if (mutation.type != 'childList' || !mutation.addedNodes.length)
{
continue;
}
Array.from(mutation.addedNodes).forEach(function(e) // or forSome if you only want to catch one object such as a button
{
if (!(e instanceof Element))
{
return;
}
// do stuff
});
}
}).observe(document.documentElement, {childList: true, subtree: true});
})();