我有一个Greasemonkey脚本,可以在Firefox和Opera中正常工作。但是,我很难使它在Chrome中工作。问题是将一个函数注入页面,该函数可以由页面中的代码调用。到目前为止,这是我正在做的事情:
首先,我获得了针对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中,我仅收到“ Uncaught ReferenceError:未定义setConfigOption”错误。实际上,在控制台中输入“ window.setConfigOption”会产生“未定义”。在Firebug和Opera开发者控制台中,该功能就在那里。
也许有另一种方法可以执行此操作,但是我的一些函数是由页面上的Flash对象调用的,我认为这使我有必要在页面上下文中使用函数。
我快速浏览了Greasemonkeywiki上unsafeWindow的替代方案,但它们看上去都很难看。我是在这里完全走错了路还是应该更仔细地研究这些?
为了使该hack的额外丑陋更容易忍受,我现在至少可以放弃使用unsafeWindow和wrappedJSObject。
我仍然没有设法使Greasemonkey Wiki的内容范围运行器正常工作。它应该做同样的事情,看起来似乎执行得很好,但是<a>例如,页面中的元素永远无法访问我的函数。我还没有弄清楚为什么会这样。
<a>
与Chrome中运行在页面上的代码进行通信的唯一方法是通过DOM,因此您必须使用黑客手段,例如<script>在代码中插入标签。请注意,如果您的脚本需要先运行页面上的所有其他内容,则这可能会引起问题。
<script>
编辑: 这是NiceAlert扩展程序执行此操作的方式:
function main () { // ... window.alert = function() {/* ... */}; // ... } var script = document.createElement('script'); script.appendChild(document.createTextNode('('+ main +')();')); (document.body || document.head || document.documentElement).appendChild(script);