2014-07-17 20 views
2

我保持的Greasemonkey腳本,並在Firefox 30結合unsafeWindow的事件在Firefox 30的Greasemonkey 2.0

我的腳本運行在該頁面得到了一些麻煩,由於Mozilla's change to the unsafeWindow API,觸發事件「MyEvent 「我的劇本對這件事很感興趣。

本次活動使用jQuery 1.6.4

之前解僱,我用這個代碼掛鉤到這個事件:

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

但由於Mozilla的變化,這將不再工作。

我試圖插入我自己的jQuery在無衝突模式,但我不認爲這可以訪問由其他jQuery實例觸發的事件?

任何想法,我怎麼能鉤入這個事件?

回答

2

的快速和骯髒的方式做到這一點,如果你不需要任何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?」顯示使用技巧。

+0

我不確定OP是否真的談論GreaseMonkey - 鏈接的博文是關於附加SDK中的內容腳本的。 –

+0

@WladimirPalant,這是因爲Greasemonkey 2.0複製了SDK更改,並引用了該SDK博客文章中的解決方法。參見[Greasemonkey 2.0公告](http://www.greasespot.net/2014/06/greasemonkey-20-release.html)。大多數GM用戶可以通過恢復到之前的GM版本來暫時修復這些不安全的窗口問題 - 至少FF 30。 –

+0

OP正在討論GreaseMonkey! @BrockAdams真棒!第二個剪輯是一種怪物,但我必須在這裏維護這個腳本。奇蹟般有效。非常感謝你! – Reini

1

只是不上unsafeWindow綁定的事件處理程序,使用常規的window對象,而不是:

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

注意第四個參數(wantsUntrusted)到addEventListener - 這一個可以讓你的事件處理程序收到不可信的事件。

+0

這不適用於由jQuery觸發的自定義事件。使用[jsbin.com/xaman/1](http://jsbin.com/xaman/1)進行測試。另外,Greasemonkey腳本不需要'wantsUntrusted'參數。 –

+0

@BrockAdams:你說的對,jQuery實現了一個「另類」事件調度機制 - 我忘記了那個巨大的WTF。當然,你需要正確派遣活動。 –

+0

是的,但OP無法控制目標頁面或jQuery如何分派事件。 –