我有一个Greasemonkey脚本,可以在Firefox和Opera中正常工作。然而,我努力让它在Chrome中运行。问题是将一个函数注入到页面中的代码可以调用的页面中。这是我到目前为止所做的:在Chrome上从Greasemonkey脚本将JS函数注入页面
首先,我得到Firefox的unsafeWindow的帮手参考。这允许我为FF和Opera(和Chrome,我想)提供相同的代码。
var uw = (this.unsafeWindow) ? this.unsafeWindow : window;
接下来,我向页面中注入一个函数。这真的只是一个很薄的包装,什么也不做,但在我的GM脚本的上下文中调用相应功能:
uw.setConfigOption = function(newValue) {
setTimeout(setConfigOption, 0, newValue);
}
然后,有相应的功能就在我的脚本:
setConfigOption = function(newValue) {
// do something with it, e.g. store in localStorage
}
末,我用一个链接来注入一些HTML到页面来调用函数。
var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);
总结: 在Firefox中,当注入链接的用户点击,它将执行上unsafeWindow,然后触发调用相应的功能在我的GM脚本的上下文超时的函数调用,然后进行实际处理。 (纠正我,如果我在这里错了。)
在Chrome中,我刚刚得到一个“未捕获的ReferenceError:setConfigOption未定义”错误。事实上,在控制台中输入“window.setConfigOption”会产生“未定义”。在Firebug和Opera开发者控制台中,函数就在那里。
也许还有另一种方法可以做到这一点,但我的一些功能是由页面上的Flash对象调用的,我相信这使我有必要在页面上下文中有功能。
我快速浏览了Greasemonkey wiki上的alternatives to unsafeWindow,但它们都显得很丑陋。我在这里完全走错了路,还是应该仔细观察这些?
解决方案:我遵循Max S.' advice,它现在可以在Firefox和Chrome中使用。因为我需要为页面提供的函数必须回调到常规函数中,所以我将整个脚本移动到页面,即完全包装到他称为“main()”的函数中。
为了让这种黑客变得更加尴尬,我现在至少可以放弃使用unsafeWindow和wrappedJSObject。
我还没有设法让Greasemonkey wiki上的content scope runner正常工作。它应该做同样的事情,它似乎执行得很好,但我的功能从不可访问页面中的<a>
元素,例如。我还没有弄清楚为什么。
我试过'content scope runner'(如果我没有弄错的话,确实如此),并且当函数可用于我的脚本时,它们似乎不可用于页面(例如锚标签)。你有任何示例代码或任何你可以链接到? 我并不十分在意执行的顺序。当我设法从页面调用一个注入函数时,我可以解决这个问题。 :) – 2010-02-20 19:37:41
内容脚本执行的顺序可以通过'run_at'语句来定义http://code.google.com/chrome/extensions/content_scripts.html – NVI 2010-02-20 20:27:24
re run_at:我没有写一个Chrome扩展,尽管(和我不打算过多地维护两个脚本)。这只是一个Greasemonkey脚本,我试图做足够的兼容性,以便Chrome可以将GM脚本“自动转换”为扩展名。 – 2010-02-20 20:32:25