如何在Greasemonkey脚本中包含远程JavaScript文件?

30

我正在尝试编写一个Greasemonkey脚本,并想使用jQuery库来实现,但我不太确定如何通过Web地址引入jQuery以开始编写。

我应该如何在Greasemonkey脚本中引入jQuery(从Google的Web服务器),以便我只需输入:

$(document).ready(function(){
  // Greasemonkey stuff here
});

我更喜欢从这个来源获取它:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" charset="utf-8"></script>

更新:非常感谢帮助,答案非常详尽。但是我使用了更多的GoogleFu并发现了这个解决方案http://joanpiedra.com/jquery/greasemonkey/

效果棒极了.. 只需将源代码更新到google托管的jQuery版本即可完成。


链接对我不起作用,这个可以:http://joanpiedra.com/portfolio/jquery-greasemonkey - newenglander
4个回答

53

在最近版本的Greasemonkey中建议使用@require注释标签。

例如:

// ==UserScript==
// @name          Hello jQuery
// @namespace     http://www.example.com/
// @description   jQuery test script
// @include       *
// @require       http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// ==/UserScript==

请注意,jQuery 1.4.1和1.4.2与此方法不兼容。

感谢Paul Tarjan指出这一点。请参见jQuery论坛帖子

还要注意这些@require语义

在用户脚本安装时,Greasemonkey将下载并保留远程文件的本地缓存副本,可以几乎即时读取。缓存副本保存在已安装的用户脚本相同的文件夹中。远程文件不会被监视更改。

请注意,截至撰写本答案时,此@require标记仅在安装时读取。如果编辑现有用户脚本以添加此标记,则会被忽略。您需要卸载并重新安装用户脚本才能使用更改。


哇,这是一个非常简单的解决方案。它还能缓存!太棒了,谢谢。 - tester
令人惊叹、完整和出色的答案。 - Dan Rosenstark
3
注意,这不适用于1.4.1或1.4.2版本:http://forum.jquery.com/topic/importing-jquery-1-4-1-into-greasemonkey-scripts-generates-an-error。 - Paul Tarjan
缓存功能非常好,我经常在我的gs脚本中使用它。我使用http://jqueryjs.googlecode.com/files/jquery-1.2.6.pack.js,因为它小巧/压缩,并且大多数时候它都有我需要的内容。 - fedmich
1
@fdrv 尝试在URL上添加查询字符串,例如添加今天的日期。http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?2018-10-08 - Lee Kowalkowski
如果你正在尝试使用Tampermonkey和jsconsole.com来记录你的userscript的控制台输出,那么这将无法工作。你会收到一个错误提示,"无法从URL加载@require"。 - John Smith

12

以下内容来自这里

// ==UserScript== 
// @name           jQueryTest 
// @namespace      http://www.example.com/
// @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() { 

    alert($); // check if the dollar (jquery) function works 
    // the next call fails 
    $("<div id='example' class='flora' title='This is my title'>I'm in 
a dialog!</div>").dialog({ 
            buttons: { 
                "Ok": function() { 
                    alert("Ok"); 
                }, 
                "Cancel": function() { 
                    $(this).dialog("close"); 
                } 
            } 
        }); 
} 

它完美地工作,但您可能希望限制它运行的网站或将jQuery js文件托管在自己的网站上,以免占用他们的带宽。


哈哈,太棒了,你刚刚发布了那个。我刚刚找到了那个链接,并替换了GM_JQ.src ='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js';谢谢你的贡献! - tester
最近版本的Greasemonkey已经不需要这样做了,您可以使用@require标签代替。 - Cheekysoft
1
使用该方法的好处是它应该在Chrome上工作,而使用@require则不会。 - Mike Buckbee
如果我需要从http加载脚本到https,它就无法工作。 - fdrv

6
您可以尝试动态创建一个脚本元素:
var script = document.createElement("script");
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
document.getElementsByTagName("head")[0].appendChild(script);

你可能需要稍等一下,直到脚本加载完成(setTimeout?)

如果我需要从http加载脚本到https,则无法正常工作。 - fdrv

2

基于Chris的回答,我按照自己的需要进行了调整,如下所示。

// ==UserScript==
// @description require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.jss
// @name         Baidu Mask
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.ibm.com/developerworks/cn/opensource/os-cn-greasemonkey/index.html
// @match        *://www.baidu.com/*
// @match        *://baike.baidu.com/*
// @match        *://zhidao.baidu.com/*
// @match        *://www.weather.com.cn/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // Your code here...

    var $j;

    function GM_wait() {
        if (typeof jQuery === 'undefined') {
            window.setTimeout(GM_wait, 100);
        }
        else {
            $j = jQuery.noConflict();
            doJob();
        }
    }

    function loadJquery() {
        // Check if jQuery's loaded

        if (typeof jQuery === 'undefined') {
            // Add jQuery
            var GM_JQ = document.createElement('script');
            GM_JQ.src = 'https://code.jquery.com/jquery-1.12.4.min.js';
            GM_JQ.type = 'text/javascript';
            GM_JQ.id = 'jquery-lyz';
            document.getElementsByTagName('head')[0].appendChild(GM_JQ);
            GM_wait();
        } else {
            doJob();
        }
    }

    loadJquery();


    function doJob() {
        if (typeof $j === 'undefined') {
            $j = $;
        }

        var url_arr = [
            {'name': "baidu", 'value': "www.baidu.com"},
            {'name': "baike", 'value': "baike.baidu.com"},
            {'name': "zhidao", 'value': "zhidao.baidu.com"},
            {'name': "weather", 'value': "http://www.weather.com.cn"},
        ];
        var url = location.href;
        var siteObj = {};
        $j(url_arr).each(function (i, item) {
            if (url.indexOf(item.value) > -1) {
                siteObj = item;
                return false;
            }
        });

        var delay_arr = [];
        var timerCount = 1;

        function hideTimer() {
            timerCount++;
            if (timerCount > 20) {
                return;
            }
            delay_arr = $j.grep(delay_arr, function (_selector, i) {
                var $ele = $j(_selector);
                var visible = $ele.is(':visible');
                console.log($ele, visible);
                if (visible) {
                    $ele.hide();
                    return false;
                }


                return true; // keep the element in the array
            });
            if (delay_arr.length > 0) {
                setTimeout(hideTimer, 500);
            }
        }

        setTimeout(hideTimer, 500);
        var $frms;
        switch (siteObj.name) {
            case 'baidu':
                $j('#content_right').hide();
                break;
            case 'baike':
                $j('.topA, .lemmaWgt-promotion-slide, .union-content, .right-ad, .lemmaWgt-promotion-vbaike, .nav-menu').hide();
                delay_arr.push('#side_box_unionAd');
                break;
            case 'zhidao':
                $j('.widget-new-graphic, #union-asplu, .jump-top-box').hide();
                delay_arr.push('.wgt-daily');
                delay_arr.push('.shop-entrance');
                delay_arr.push('.cms-slide');
                delay_arr.push('.nav-menu');
                $frms = $j('iframe');
                $frms.hide();
                break;
            case 'weather':
                $j('.right, .hdImgs, .tq_zx, #di_tan, #zu_dui').hide();
                //delay_arr.push('.wgt-daily');
                $frms = $j('iframe');
                $frms.hide();
                break;
        }
    }

})();

我的脚本需要在不同的网站上工作,有些网站已经包含了jQuery,而有些没有,所以我必须进行测试。"require"的方式在这里不起作用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接