在Chrome中的用户脚本之间传输信息

时间:2013-01-31 07:01:42

标签: javascript google-chrome tabs greasemonkey userscripts

当在另一个选项卡中满足某些条件时,我需要在一个选项卡中的页面上执行一个函数。我需要做的就是向另一个标签发送一些推动。我已经尝试了很多东西与计时器一起进行轮询:

  • GM_setValue(Chrome中不支持)
  • 设置top.item(显然在标签之间不起作用)
  • Cookie(即使我的用户脚本在同一个域中的两个标签中运行,但这似乎不起作用)

还有其他想法吗?是的,我确实需要使用Chrome,即使它似乎打算在这个>中挫败我。>

1 个答案:

答案 0 :(得分:2)

由于标签位于同一个域中,因此您可以使用localStorage

  1. 将脚本设置为在两个页面上运行,EG:

    // @include  http://YOUR_SERVER.COM/YOUR_PATH/pitcher/*
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/batter/*
    
  2. 请确保您可以告诉哪个页面是哪个。例如,通过URL或一些不同的内容。

  3. 发送页面只根据需要设置值,EG:

    localStorage.setItem ('targetAddress', 'http://puppies.com/');
    
  4. 接收页面会侦听storage个事件,例如:

    $(window).bind ("storage", function (zEvent) {
        ...
    } );
    

    window.addEventListener ("storage", function (zEvent) {
        ...
    }, false);
    

  5. 总而言之,一个完整的脚本,适用于Firefox和Chrome(可能还有Opera等)。

    您可以针对this "sender" pagethis "receiver" page进行测试。

    // ==UserScript==
    // @name     _Cross tab, same domain communication
    // @include  http://jsbin.com/ihoboz/*pitcher*
    // @include  http://jsbin.com/ihoboz/*batter*
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/pitcher/*
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/batter/*
    // @require  http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
    // @grant    GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in Greasemonkey 1.0.   It restores the sandbox.
    */
    
    function GM_main ($) {
        /*-- Is this the sending or receiving page?
            In our example, the sender has "pitcher" in the URL,
            while the receiver has "batter" in the URL
        */
        var isSender = false, isReceiver = false;
    
        if (/pitcher/i.test (location.href) ) {
            isSender    = true;
        }
        else if (/batter/i.test (location.href) ) {
            isReceiver  = true;
        }
    
        if (isSender) {
            //-- Add 2 buttons to change the data we send to the other tab.
            $("body").prepend (
                '<button class="gmTestButtons">Set the transmitted value.</button>' +
                '<button class="gmTestButtons">Reset the transmitted value.</button>'
            );
    
            $("button.gmTestButtons").click ( function () {
    
                if (/^Set the transmitted/.test (this.textContent) ) {
                    localStorage.setItem ('targetAddress', 'http://puppies.com/');
                }
                else {
                    localStorage.setItem ('targetAddress', 'http://unicorns.com/');
                }
            } );
        }
        else if (isReceiver) {
            //-- Listen for changes in local storage
            $(window).bind ("storage", function (zEvent) {
                var varName     = zEvent.originalEvent.key;
                var newValue    = zEvent.originalEvent.newValue;
    
                alert (
                    'Received new variable, "'   + varName
                    + '", with a new value of: ' + newValue
                );
            } );
        }
    }
    
    //-- Style and/or postion our buttons
    GM_addStyle ( "                                 \
        button.gmTestButtons {                      \
            margin:                 1em;            \
            padding:                1ex 1em;        \
            font-size:              20px;           \
            background:             pink;           \
        }                                           \
    " );
    
    
    //--- The rest of this just loads jQuery in a cross-browser way.
    //
    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);
    }