将 JS 函数从 Chrome 上的 Greasemonkey 脚本注入页面 [英] Injecting JS functions into the page from a Greasemonkey script on Chrome

查看:58
本文介绍了将 JS 函数从 Chrome 上的 Greasemonkey 脚本注入页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在 Firefox 和 Opera 中运行良好的 Greasemonkey 脚本.然而,我很难让它在 Chrome 中工作.问题是将一个函数注入到页面中,该函数可以被页面中的代码调用.这是我目前所做的:

I have a Greasemonkey script that works just fine in Firefox and Opera. I struggle with getting it to work in Chrome, however. The problem is injecting a function into the page that can be invoked by code from the page. Here's what I'm doing so far:

首先,我获得了 Firefox 的 unsafeWindow 的帮助参考.这使我可以为 FF 和 Opera(以及 Chrome,我认为)拥有相同的代码.

First, I get a helper reference to the unsafeWindow for Firefox. This allows me to have the same code for FF and Opera (and Chrome, I thought).

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

接下来,我将一个函数注入页面.它实际上只是一个非常薄的包装器,除了在我的 GM 脚本的上下文中调用相应的函数之外什么都不做:

Next, I inject a function into the page. It's really just a very thin wrapper that does nothing but invoking the corresponding function in the context of my GM script:

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);
}

然后,在我的脚本中有相应的函数:

Then, there's the corresponding function right in my script:

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage
}

最后,我将一些 HTML 注入到页面中,并带有调用该函数的链接.

Last, I inject some HTML into the page with a link to invoke the function.

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 脚本的上下文中调用相应的函数,然后执行实际处理.(如果我错了,请纠正我.)

To summarize: In Firefox, when the user clicks that injected link, it will execute the function call on the unsafeWindow, which then triggers a timeout that invokes the corresponding function in the context of my GM script, which then does the actual processing. (Correct me if I'm wrong here.)

在 Chrome 中,我只收到未捕获的 ReferenceError:setConfigOption 未定义"错误.事实上,在控制台中输入window.setConfigOption"会产生未定义".在 Firebug 和 Opera 开发者控制台中,该功能就在那里.

In Chrome, I just get a "Uncaught ReferenceError: setConfigOption is not defined" error. And indeed, entering "window.setConfigOption" into the console yields an "undefined". In Firebug and the Opera developer console, the function is there.

也许还有另一种方法可以做到这一点,但我的一些函数是由页面上的 Flash 对象调用的,我认为这使得我有必要在页面上下文中使用函数.

Maybe there's another way to do this, but a few of my functions are invoked by a Flash object on the page, which I believe makes it necessary that I have functions in the page context.

我快速浏览了 Greasemonkey wiki 上的不安全窗口的替代方案,但是他们都看起来很丑.我在这里完全走错了路,还是应该更仔细地研究这些?

I took a quick look at the alternatives to unsafeWindow on the Greasemonkey wiki, but they all look pretty ugly. Am I completely on the wrong track here or should I look more closely into these?

解决方案:我关注了 最大 S.'建议,它现在可以在 Firefox 和 Chrome 中使用.因为我需要在页面上可用的函数必须回调到常规函数中,所以我将整个脚本移到了页面中,即它完全包装在他称为main()"的函数中.

RESOLUTION: I followed Max S.' advice and it works in both Firefox and Chrome now. Because the functions I needed to be available to the page had to call back into the regular ones, I moved my whole script to the page, i.e. it is completely wrapped into the function he called 'main()'.

为了让这个 hack 的额外丑陋更容易忍受,我现在至少可以放弃使用 unsafeWindow 和wrappedJSObject.

To make the extra uglyness of that hack a little bit more bearable, I could at least drop the usage of unsafeWindow and wrappedJSObject now.

我仍然没有让 Greasemonkey wiki 中的 content scope runner 正常工作.它应该做同样的事情并且它似乎执行得很好,但是我的函数永远无法被页面中的 <a> 元素访问,例如.我还没有弄清楚为什么会这样.

I still haven't managed to get the content scope runner from the Greasemonkey wiki working. It should do the same and it seems to execute just fine, but my functions are never accessible to <a> elements from the page, for example. I haven't yet figured out why that is.

推荐答案

在 Chrome 中与页面上运行的代码进行通信的唯一方法是通过 DOM,因此您必须使用像插入 <script> 标签与您的代码.请注意,如果您的脚本需要在页面上的其他所有内容之前运行,这可能会证明存在错误.

The only way to communicate with the code running on the page in Chrome is through the DOM, so you'll have to use a hack like inserting a <script> tag with your code. Note that this may prove buggy if your script needs to run before everything else on the page.

Nice Alert 扩展程序的作用如下这个:

function main () {
  // ...
  window.alert = function() {/* ... */};
  // ...
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);

这篇关于将 JS 函数从 Chrome 上的 Greasemonkey 脚本注入页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆