Greasemonkey脚本替换jQuery插件函数?

时间:2012-04-15 15:02:25

标签: javascript jquery greasemonkey

我正在尝试为Firefox编写一个Greasemonkey脚本,以便在检测到一个没有焦点的窗口时更改某些页面的行为。我希望页面继续运行,就像它仍然处于焦点一样,即使我有另一个标签或窗口处于活动状态。

我开始查看CAPS Security Policies,它似乎适用于内联Javascript(window.onfocuswindow.onblur),但对外部jQuery脚本插件访问焦点事件没有影响。

这是我的测试页面,它使用jQuery插件来检测焦点。插件在这里是内联的,但在某些情况下也可能是外部脚本。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
    <title>jQuery focus test</title>
<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">

(function($) {
    $.fn.focuscheck = function() {
        function focusOn () {
            document.getElementById('console').innerHTML += '<div>Focus event handler fired.</div>';
        };
        function focusOff () {
            document.getElementById('console').innerHTML += '<div>Blur event handler fired.</div>';
        };

        $(window).bind('focus', focusOn);
        $(window).bind('blur', focusOff);
    };
})(jQuery);

</script>
</head>

<body>    
    <div id="console"></div>
    <script type="text/javascript">
    $('#func').focuscheck();
    </script>
</body>

</html>

我的Greasemonkey脚本。我正在尝试从joanpiedra.com调整jQuery Greasemonkey代码。在这种情况下,我试图从我的测试页面中完全替换focuscheck jQuery插件函数代码。所有行都与原始行相同,但function focusOff()应显示不同的结果。我不知道是否有办法在不更换整个功能的情况下执行此操作。如果这是一个选项,我可能只想用focusOff替换单个$(window).bind('blur', focusOff);函数或行。

目前,Greasemonkey脚本在我的测试页面上不起作用。输出没有变化。另外,我不确定是否需要将jQuery添加到我的Greasemonkey脚本中,因为页面已经加载了它。

// ==UserScript==
// @name          jQuery
// @namespace     http://www.joanpiedra.com/jquery/greasemonkey
// @description   Play nicely with jQuery and Greasemonkey
// @author        Joan Piedra
// @homepage      http://www.joanpiedra.com/jquery/greasemonkey
// @include       *
// ==/UserScript==

// Add jQuery
var GM_JQ = document.createElement('script');
GM_JQ.src = 'http://jquery.com/src/jquery-latest.js';
GM_JQ.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(GM_JQ);

// Check if jQuery's loaded
function GM_wait() {
    if(typeof unsafeWindow.jQuery == 'undefined') { window.setTimeout(GM_wait,100); }
    else { $ = unsafeWindow.jQuery; letsJQuery(); }
}
GM_wait();

// All your GM code must be inside this function
function letsJQuery() {
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.innerHTML = "(function($){\
        \
        $.fn.focuscheck = function(){\
            function focusOn () {\
                document.getElementById('console').innerHTML += '<div>Focus event handler fired.</div>';\
            };\
            function focusOff () {\
                document.getElementById('console').innerHTML += '<div>CHANGED event handler.</div>';\
            };\
        \
        $(window).bind('focus', focusOn);\
        $(window).bind('blur', focusOff);\
        };\
    })(jQuery);";

    document.getElementsByTagName('head')[0].appendChild(script);   
}

1 个答案:

答案 0 :(得分:2)

  

我不知道是否有办法在不更换整个过程的情况下执行此操作   功能

是的,有。请参阅下面的代码。

  

另外,我不确定是否需要将jQuery添加到我的Greasemonkey脚本中   或不,因为页面已加载它。

你不必。请参阅下面的代码。

html (与你的相同 - 我刚刚将“从内联JS中解雇”添加到innerHTML

<html lang="en">
.
.
function focusOn () {
   document.getElementById('console').innerHTML += '<div>Focus event handler fired from inline JS.</div>';
};
function focusOff () {
   document.getElementById('console').innerHTML += '<div>Blur event handler fired from inline JS.</div>';
};
.
.
</html>

GM脚本

// ==UserScript==
// @name           TESTE 2
// @namespace      TESTE 2
// @description    TESTE 2
// @include        file:///*
// ==/UserScript==


$ = unsafeWindow.$
$(window).off('blur')

function focusOff () {
    document.getElementById('console').innerHTML += '<div>Blur event handler fired from Greasemonkey.</div>';
};

$(window).on('blur', focusOff);

结果

result image

在这里,为什么你不应该使用unsafeWindowhttp://wiki.greasespot.net/UnsafeWindow

修改

在评论中关于您的问题

  

谢谢。这正是我想要的。我会调查一下   使用安全包装而不是unsafeWindow。如果你不介意的话   后续问题:Slide Panel demo - 我试图适应类似的问题   用于覆盖click函数的代码   $('.btn-slide').unbind('click')然后添加一个新函数,但它   不太有效。记录事件,但按钮仍然存在   激活。 $('.btn-slide').bind('click', function(event) { event.preventDefault(); console.log('button clicked'); });我怎么能   阻止幻灯片动画?

新代码:

// ==UserScript==
// @name           TESTE 3
// @namespace      TESTE 3
// @description    TESTE 3
// @include        http://www.webdesignerwall.com/demo/jquery/*
// ==/UserScript==

$ = unsafeWindow.$

$(window).load(function(){
    $('.btn-slide')
        .unbind('click')
        .bind('click', function(event) {
            alert('my function here')
            console.log('button clicked')
        })
});