2

当在另一个选项卡中满足某些条件时,我需要在一个选项卡的页面上执行功能。我需要做的就是向另一个选项卡发送某种轻推。我已经尝试了很多与计时器结合使用的方法来保持轮询:

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

还有其他想法吗?是的,我确实需要使用 Chrome,尽管它似乎有意在此阻止我 >.>

4

1 回答 1

2

由于选项卡位于同一域中,因此您可以使用localStorage.

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

    // @include  http://YOUR_SERVER.COM/YOUR_PATH/pitcher/*
    // @include  http://YOUR_SERVER.COM/YOUR_PATH/batter/*
    
  2. 确保你能分辨出哪个页面是哪个页面。通过 URL,例如,或一些不同的内容。

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

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

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

    或者

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


总而言之,这是一个完整的脚本,它可以在 Firefox 和 Chrome(可能还有 Opera 和其他)中运行。

您可以针对这个“发送者”页面这个“接收者”页面对其进行测试。

// ==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);
}
于 2013-01-31T09:08:31.870 回答