代码之家  ›  专栏  ›  技术社区  ›  Alekc

如何在google chrome的greasemonkey脚本中使用jquery?

  •  153
  • Alekc  · 技术社区  · 15 年前

    如你们所知,google chrome对greasemonkey脚本设置了一些严格的限制。

    铬不支持 @require , @resource , unsafeWindow , GM_registerMenuCommand , GM_setValue GM_getValue .

    如果不需要,我找不到在google chrome下的greasemonkey脚本中包含jquery库的方法。

    有人对这件事有什么建议吗?

    11 回复  |  直到 8 年前
        1
  •  190
  •   Rublacava    9 年前

    "User Script Tip: Using jQuery - Erik Vold's Blog"

    // ==UserScript==
    // @name         jQuery For Chrome (A Cross Browser Example)
    // @namespace    jQueryForChromeExample
    // @include      *
    // @author       Erik Vergobbi Vold & Tyler G. Hicks-Wright
    // @description  This userscript is meant to be an example on how to use jQuery in a userscript on Google Chrome.
    // ==/UserScript==
    
    // a function that loads jQuery and calls a callback function when jQuery has finished loading
    function addJQuery(callback) {
      var script = document.createElement("script");
      script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js");
      script.addEventListener('load', function() {
        var script = document.createElement("script");
        script.textContent = "window.jQ=jQuery.noConflict(true);(" + callback.toString() + ")();";
        document.body.appendChild(script);
      }, false);
      document.body.appendChild(script);
    }
    
    // the guts of this userscript
    function main() {
      // Note, jQ replaces $ to avoid conflicts.
      alert("There are " + jQ('a').length + " links on this page.");
    }
    
    // load jQuery and execute the main function
    addJQuery(main);
    
        2
  •  43
  •   Jeremy Meo    12 年前

    我已经编写了一些基于 Erik Vold's script 帮助我在文档中运行函数、代码和其他脚本。您可以使用它们将jquery加载到页面中,然后在全局 window 范围。

    示例用法

    // ==UserScript==
    // @name           Example from http://stackoverflow.com/q/6834930
    // @version        1.3
    // @namespace      http://stackoverflow.com/q/6834930
    // @description    An example, adding a border to a post on Stack Overflow.
    // @include        http://stackoverflow.com/questions/2246901/*
    // ==/UserScript==
    
    var load,execute,loadAndExecute;load=function(a,b,c){var d;d=document.createElement("script"),d.setAttribute("src",a),b!=null&&d.addEventListener("load",b),c!=null&&d.addEventListener("error",c),document.body.appendChild(d);return d},execute=function(a){var b,c;typeof a=="function"?b="("+a+")();":b=a,c=document.createElement("script"),c.textContent=b,document.body.appendChild(c);return c},loadAndExecute=function(a,b){return load(a,function(){return execute(b)})};
    
    loadAndExecute("//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js", function() {
        $("#answer-6834930").css("border", ".5em solid black");
    });
    

    你可以 click here 要安装它,如果你相信我没有试图欺骗你安装恶意的东西,而且没有人编辑我的文章指向其他东西。重新加载页面,你会看到我的帖子周围有一个边框。

    功能

    load(url, onLoad, onError)

    在加载脚本 url 在文件里。可选地,可以为 onLoad onError .

    execute(functionOrCode)

    在文档中插入函数或代码字符串并执行它。函数在被插入之前被转换为源代码,因此它们失去了当前的作用域/闭包,并在全局 窗口 范围。

    loadAndExecute(url, functionOrCode)

    快捷方式;它从 网址 ,然后插入并执行 functionOrCode 如果成功的话。

    代码

    function load(url, onLoad, onError) {
        e = document.createElement("script");
        e.setAttribute("src", url);
    
        if (onLoad != null) { e.addEventListener("load", onLoad); }
        if (onError != null) { e.addEventListener("error", onError); }
    
        document.body.appendChild(e);
    
        return e;
    }
    
    function execute(functionOrCode) {
        if (typeof functionOrCode === "function") {
            code = "(" + functionOrCode + ")();";
        } else {
            code = functionOrCode;
        }
    
        e = document.createElement("script");
        e.textContent = code;
    
        document.body.appendChild(e);
    
        return e;
    }
    
    function loadAndExecute(url, functionOrCode) {
        load(url, function() { execute(functionOrCode); });
    }
    
        3
  •  16
  •   Brock Adams    12 年前

    使用jQuery 不怕冲突 ,通过呼叫 jQuery.noConflict(true) . 像这样:

    function GM_main ($) {
        alert ('jQuery is installed with no conflicts! The version is: ' + $.fn.jquery);
    }
    
    add_jQuery (GM_main, "1.7.2");
    
    function add_jQuery (callbackFn, jqVersion) {
        jqVersion       = jqVersion || "1.7.2";
        var D           = document;
        var targ        = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        var scriptNode  = D.createElement ('script');
        scriptNode.src  = 'http://ajax.googleapis.com/ajax/libs/jquery/'
                        + jqVersion
                        + '/jquery.min.js'
                        ;
        scriptNode.addEventListener ("load", function () {
            var scriptNode          = D.createElement ("script");
            scriptNode.textContent  =
                'var gm_jQuery  = jQuery.noConflict (true);\n'
                + '(' + callbackFn.toString () + ')(gm_jQuery);'
            ;
            targ.appendChild (scriptNode);
        }, false);
        targ.appendChild (scriptNode);
    }
    


    但是, 对于跨浏览器脚本,如果可以,为什么不利用jquery的一个漂亮、快速的本地副本呢?

    下面是一个chrome用户脚本和一个greasemonkey脚本,它使用nice local @require jquery的副本(如果平台支持)。

    // ==UserScript==
    // @name     _Smart, cross-browser jquery-using script
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/*
    // @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
    // @grant    GM_info
    // ==/UserScript==
    
    function GM_main ($) {
        alert ('jQuery is installed with no conflicts! The version is: ' + $.fn.jquery);
    }
    
    if (typeof jQuery === "function") {
        console.log ("Running with local copy of jQuery!");
        GM_main (jQuery);
    }
    else {
        console.log ("fetching jQuery from some 3rd-party server.");
        add_jQuery (GM_main, "1.7.2");
    }
    
    function add_jQuery (callbackFn, jqVersion) {
        var jqVersion   = jqVersion || "1.7.2";
        var D           = document;
        var targ        = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        var scriptNode  = D.createElement ('script');
        scriptNode.src  = 'http://ajax.googleapis.com/ajax/libs/jquery/'
                        + jqVersion
                        + '/jquery.min.js'
                        ;
        scriptNode.addEventListener ("load", function () {
            var scriptNode          = D.createElement ("script");
            scriptNode.textContent  =
                'var gm_jQuery  = jQuery.noConflict (true);\n'
                + '(' + callbackFn.toString () + ')(gm_jQuery);'
            ;
            targ.appendChild (scriptNode);
        }, false);
        targ.appendChild (scriptNode);
    }
    
        4
  •  15
  •   Camilo Martin    13 年前

    如果页面已经有jquery,那么只需遵循以下模板:

    // ==UserScript==
    // @name          My Script
    // @namespace     my-script
    // @description   Blah
    // @version       1.0
    // @include       http://site.com/*
    // @author        Me
    // ==/UserScript==
    
    var main = function () {
    
        // use $ or jQuery here, however the page is using it
    
    };
    
    // Inject our main script
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.textContent = '(' + main.toString() + ')();';
    document.body.appendChild(script);
    
        5
  •  7
  •   Stiger    10 年前

    简单的方法是 required 关键词:

    // @require     http://code.jquery.com/jquery-latest.js
    
        6
  •  7
  •   Jeff Atwood    9 年前

    有一个非常简单的方法可以绕过,包括jquery for chrome脚本的完整副本 当这些脚本实际上没有使用任何特权功能时 (通用汽车公司的职能等)

    只需将脚本本身插入到页面dom并执行!最好的一点是,这种技术在firefox+greasemonkey上同样有效,因此您可以对这两个脚本使用相同的脚本:

    var script = document.createElement("script");
    script.type = "text/javascript";
    script.textContent = "(" + threadComments.toString() + ")(jQuery)";
    document.body.appendChild(script);
    
    function threadComments($) {
        // taken from kip's http://userscripts-mirror.org/scripts/review/62163
        var goodletters = Array('\u00c0','\u00c1','\u00c2','\u00c3','\u00c4','\u00c5','\u00c6','\u00c7'
                                 ,'\u00c8','\u00c9','\u00ca','\u00cb','\u00cc','\u00cd','\u00ce','\u00cf'
                                          ,'\u00d1','\u00d2','\u00d3','\u00d4','\u00d5','\u00d6'         
                                 ,'\u00d8','\u00d9','\u00da','\u00db','\u00dc','\u00dd'                  
                                 ,'\u00e0','\u00e1','\u00e2','\u00e3','\u00e4','\u00e5','\u00e6','\u00e7'
                                 ,'\u00e8','\u00e9','\u00ea','\u00eb','\u00ec','\u00ed','\u00ee','\u00ef'
                                          ,'\u00f1','\u00f2','\u00f3','\u00f4','\u00f5','\u00f6'         
                                 ,'\u00f8','\u00f9','\u00fa','\u00fb','\u00fc','\u00fd'         ,'\u00ff').join('');
    
        // from Benjamin Dumke's http://userscripts-mirror.org/scripts/review/68252
        function goodify(s)
          {
             good = new RegExp("^[" + goodletters + "\\w]{3}");
             bad = new RegExp("[^" + goodletters + "\\w]");
             original = s;
             while (s.length >3 && !s.match(good)) {
                s = s.replace(bad, "");
                }
             if (!s.match(good))
             {
               // failed, so we might as well use the original
               s = original;
             }
             return s;
          }  
    
        in_reply_to = {};
    
    
        function who(c, other_way) {
    
    
            if (other_way)
            {
                // this is closer to the real @-reply heuristics
                m = /@(\S+)/.exec(c);
            }
            else
            {
                m = /@([^ .:!?,()[\]{}]+)/.exec(c);
            }
            if (!m) {return}
            if (other_way) {return goodify(m[1]).toLowerCase().slice(0,3);}
            else {return m[1].toLowerCase().slice(0,3);}
        }
    
        function matcher(user, other_way) {
            if (other_way)
            {
                return function () {
                    return goodify($(this).find(".comment-user").text()).toLowerCase().slice(0,3) == user
                    }
            }
            else
            {
                return function () {
                    return $(this).find(".comment-user").text().toLowerCase().slice(0,3) == user
                    }
            }
        }
    
        function replyfilter(id) {
            return function() {
                return in_reply_to[$(this).attr("id")] == id;
            }
        }
    
        function find_reference() {
            comment_text = $(this).find(".comment-text").text();
            if (who(comment_text))
            {
                fil = matcher(who(comment_text));
                all = $(this).prevAll("tr.comment").filter(fil);
                if (all.length == 0)
                {
                    // no name matched, let's try harder
                    fil = matcher(who(comment_text, true), true);
                    all = $(this).prevAll("tr.comment").filter(fil);
                    if (all.length == 0) {return}
                }
                reference_id = all.eq(0).attr("id");
                in_reply_to[$(this).attr("id")] = reference_id;
            }
        }
    
    
        // How far may comments be indented?
        // Note that MAX_NESTING = 3 means there are
        // up to *four* levels (including top-level)
        MAX_NESTING = 3
    
        // How many pixels of indentation per level?
        INDENT = 30
    
        function indenter(parent) {
    
            for (var i = MAX_NESTING; i > 0; i--)
            {
                if (parent.hasClass("threading-" + (i-1)) || (i == MAX_NESTING && parent.hasClass("threading-" + i)))
                {
                    return function() {
                        $(this).addClass("threading-" + i).find(".comment-text").css({"padding-left": INDENT*i});
                    }
                }
            }
    
            return function() {
                $(this).addClass("threading-1").find(".comment-text").css({"padding-left": INDENT});
            }
    
        }
    
        function do_threading(){
            id = $(this).attr("id");
            replies = $(this).nextAll("tr.comment").filter(replyfilter(id));
            ind = indenter($(this));
            replies.each(ind);
            replies.insertAfter(this);
        }
    
        function go() {
            $("tr.comment").each(find_reference);
            $("tr.comment").each(do_threading);
        }
    
        $.ajaxSetup({complete: go});
        go();
    }
    

    (毫无歉意地从meta.stackoverflow上的shog9被盗,因为他没有把它移到这里,我不得不删除meta post…)

        7
  •  4
  •   NVI    15 年前

    此外,还可以将脚本打包为jquery到chrome扩展。见 Google Chrome's Content Scripts

    chrome扩展不同于greasemonkey脚本,它可以自动更新自己。

        8
  •  4
  •   cyphunk    12 年前

    更简单的解决方案:将jquery.min.js的内容剪切并粘贴到用户脚本的顶部。完成。

    我发现推荐的答案有很多问题。addjquery()解决方案适用于大多数页面,但在许多页面上都有错误。如果遇到问题,只需将jquery内容复制并粘贴到脚本中。

        9
  •  2
  •   gnarf    14 年前

    我想知道你是否不能依赖 document.defaultView.jQuery 在你的gm脚本ala中:

    if (document.defaultView.jQuery) {
      jQueryLoaded(document.defaultView.jQuery);
    } else {
      var jq = document.createElement('script');
      jq.src = 'http://jquery.com/src/jquery-latest.js';
      jq.type = 'text/javascript';
      document.getElementsByTagName('head')[0].appendChild(jq);
      (function() { 
        if (document.defaultView.jQuery) jQueryLoaded(document.defaultView.jQuery);
        else setTimeout(arguments.callee, 100);
      })();
    }
    
    function jQueryLoaded($) {
      console.dir($);
    }
    
        10
  •  1
  •   Community CDub    8 年前

    另一种方法是修改脚本以手动加载jquery。例子来自 http://joanpiedra.com/jquery/greasemonkey/ :

    // 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
    }
    

    编辑:DRATS! 在测试之后,这段代码似乎不起作用,因为google chrome在一个与实际网页不同的作用域/进程中运行用户脚本/扩展。您可以使用xmlhttprequest下载jquery代码,然后对其进行求值,但是您必须在允许 Cross-Origin Resource Sharing 使用 Access-Control-Allow-Origin: * 标题。悲哀地 NONE of the current CDNs 支持jquery。

        11
  •  -1
  •   Andrey    14 年前

    将jquery嵌入chrome控制台的完美扩展,正如您所想象的那样简单。如果jquery已经嵌入到页面中,则此扩展还会显示。

    这个扩展用于将jquery嵌入到您想要的任何页面中。它允许在控制台shell中使用jquery(您可以通过“ctrl+shift+j”调用chrome控制台)。

    若要将jquery嵌入选定的选项卡,请单击“扩展”按钮。

    链接到扩展名: https://chrome.google.com/extensions/detail/gbmifchmngifmadobkcpijhhldeeelkc