使用Greasemonkey 2.0绑定到Firefox 30中的unsafeWindow事件

时间:2014-07-17 11:44:15

标签: javascript jquery firefox greasemonkey

由于Firefox 30中的Mozilla's change to the unsafeWindow API,我正在维护一个Greasemonkey脚本并遇到麻烦。

我的脚本运行的页面,触发事件“MyEvent”,我的脚本对该事件感兴趣。

使用jQuery 1.6.4

触发事件

之前,我使用此代码挂钩此事件:

var jQuery = unsafeWindow.jQuery;
jQuery(unsafeWindow.document)
    .bind("MyEvent", function() {
        console.log("MyEvent Triggered!");
    });

但是由于Mozilla的改变,这将不再适用。

我试图在无冲突模式下插入自己的jQuery,但我不认为这可以访问由其他jQuery实例触发的事件?

我有什么想法可以参与这个活动吗?

2 个答案:

答案 0 :(得分:3)

快速而肮脏的方式,如果您不需要任何GM_功能不要@require您的拥有jQuery ,就是使用@grant none模式。这有效:

// ==UserScript==
// @name     _unsafeWindow tests
// @include  http://jsbin.com/xaman/*
// @grant    none
// ==/UserScript==

var jQuery = window.jQuery;
jQuery(document).bind ("MyEvent", function () {
    console.log ("From GM script: MyEvent caught!");
} );

如果您确实需要GM_个功能,有时可以使用the new exportFunction() 不幸的是,jQuery和jQuery事件处理是一个特例。根据您的尝试,您将收到如下错误消息:

  

拒绝访问财产'处理程序'的权限   或
  CloneNonReflectorsWrite错误

我发现使用任何新的unsafeWindow功能都无法做到这一点。你唯一的办法是注入代码。像这样:

// ==UserScript==
// @name     _unsafeWindow tests
// @include  http://jsbin.com/xaman/*
// @require  http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.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.
*/
function myEventHandler (zEvent) {
    console.log (
        'From GM script: "' + zEvent.type + '" triggered on ', zEvent.target
    );
}

function bindMyEvent () {
    //-- Gets "jQuery is not defined" if GM script does not also use jQuery.
    jQuery(document).bind ("MyEvent", myEventHandler);
    console.log ("The jQuery version being used is: ", jQuery.fn.jquery);
}

//-- Create A COPY OF myEventHandler in the target page scope:
addJS_Node (myEventHandler);
//-- Create A COPY OF bindMyEvent in the target page scope and immediately run it.
addJS_Node (null, null, bindMyEvent);

function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

您可以针对this jsBin page

测试这两个脚本

如果您需要在注入的事件处理程序中运行/调用GM_函数,请使用" How to call Greasemonkey's GM_ functions from code that must run in the target page scope?"中显示的技术。

答案 1 :(得分:1)

不要在unsafeWindow上绑定事件处理程序,而是使用常规window对象:

window.document.addEventListener("MyEvent", function() {
  console.log("MyEvent Triggered!");
}, false, true);

请注意第四个参数(wantsUntrusted)到addEventListener - 这个参数允许您的事件处理程序接收不受信任的事件。