【问题标题】:jQuery queue in Chrome userscript with popups?带有弹出窗口的Chrome用户脚本中的jQuery队列?
【发布时间】:2011-04-24 02:55:33
【问题描述】:

我想问是否有可能构建 Chrome 或 Greasemonkey 脚本女巫可以打开队列中的所有弹出窗口。到目前为止,我为此有 2 个单独的脚本,但效果不佳,因为弹出窗口具有反垃圾邮件功能,不允许同时使用太多。

我想要做的是以队列方式处理弹出链接数组,并且仅在上一个关闭时打开下一个。当它涉及队列和任何类型的事件绑定时,我没有经验。

所以我得到了资源:

1) 已经准备好的链接数组

var URL_Array = [];

$('form[name="form_gallery"] .img img').each(function(i,e){
    // Format URL array here
    if($(this).closest('.object').children('.phs_voted_count').length == 0){
        var string = e.src;
        var nowBrake = string.substring(string.length-7,7);
        var splited = nowBrake.split('/');
        var urlStr = '/window/friend/gallery_view/'+splited[3]+'/'+splited[4]+'.html';
        URL_Array[i] = urlStr;
    }
});

2) 在弹出窗口中对图像进行投票的脚本

    /*######################################################*/  
    var voteBy            = '#vte_mark_12';            // Prefered vote icon
    var voteDefault       = '#vte_mark_5';             // Default vote icon
    var voteFormLoc       = 'image_voting';            // Image voting popups form
    var buyExtraVote      = 'image_voting_buy';        // If run out of votes buy more
    var captchaLoc        = 'input[name="captcha"]';   // Captcha input field
    var captchaTxt        = 'Enter captcha text!';     // Captcha alert text
    var simpatyFormId     = '#sym_send';               // Simpaty window form

    var startScript          = true; 
    var formProcessedAlready = false; // Used to check if image already was voted
    /*######################################################*/  

$(function(){
    if(startScript){
        if($(captchaLoc).length > 0){
            alert(captchaTxt);
            $(captchaLoc).focus().css('border', '2px solid red');
            return false;
        }else{
            if($('#50').length > 0){
                $('#50').attr('checked', true);
                $('form').attr('id', buyExtraVote);
                $('#'+buyExtraVote).submit();
            }else{
                $('form').attr('id', voteFormLoc);
                if($(voteBy).length > 0){
                    $(voteBy).attr('checked', true);
                    setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                }else if($(voteDefault).length > 0){
                    $(voteDefault).attr('checked', true);
                    setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                }else{
                    // If we have simpaty box autocast submit
                    if($(simpatyFormId).length > 0){
                        if($(captchaLoc).length > 0){
                            alert(captchaTxt);
                            $(captchaLoc).focus().css('border', '2px solid red');
                            return false;
                        }else{
                            $(simpatyFormId).submit();
                            formProcessedAlready = true;
                        }
                    }else{
                        formProcessedAlready = true;
                    }
                }
            }
        }

        if(formProcessedAlready){
            self.close();
        }
    }
});

据我所知,它应该是这样的:
1) 获取所有未投票的网址并形成数组(完成)
2) 排队打开所有弹出窗口
3) 启动第一个弹出窗口
4) 投票完成,弹出窗口关闭(完成)
5) 启动第二个弹出窗口
6) 数组完成后切换到下一页(完成)

你怎么看?

【问题讨论】:

  • 我最好只弹出一个窗口,这样任何防病毒程序都不会阻止它。启动第一个弹出窗口 -> 投票完成并使用新表单刷新弹出窗口 -> ...
  • 我每次都愿意提供任何一种或新的解决方案。我将是唯一会使用它的人,所以我不担心任何阻塞。

标签: javascript jquery userscripts


【解决方案1】:
  • 主页和弹出窗口的确切 URL 是什么?
  • 您使用的是什么版本的 jQuery,您是如何包含它的?

确切的 URL 很重要,因为脚本需要同时处理主页和弹出窗口,并在每个页面上进行不同的操作。

他们有两种主要的处理方式。要么:

  1. 使用include 指令确保脚本在主页和弹出窗口上都运行,但会根据页面类型切换其行为。这将有两个不同的脚本实例同时运行,这不是问题。

  2. 使用 include 和可能的 exclude 指令来确保脚本在主页上运行。然后让弹出式打开代码操作表单。


方法一的做法如下:

(1) 假设主页是这样的:
somewhere.com/main/*
弹出页面就像:
somewhere.com/window/friend/gallery_view/*
确保脚本的包含指令在两组页面上触发。

(2) 确保 jQuery 在这两种页面上都可用。推荐使用 jQuery 1.5.1。 jQuery 1.3.2 可能不适用于以下代码。

(3) 那么下面的代码应该可以工作了:

var URL_Array   = [];
var PopupQueue  = $({});    //-- jQuery on an empty object - a perfect queue holder

//--- Is this a popup window or the main page?

if ( /\/window\/friend\/gallery_view\//i.test (window.location.href) )
{
    //--- This is a popup page

    /*######################################################*/  
    var voteBy            = '#vte_mark_12';            // Prefered vote icon
    var voteDefault       = '#vte_mark_5';             // Default vote icon
    var voteFormLoc       = 'image_voting';            // Image voting popups form
    var buyExtraVote      = 'image_voting_buy';        // If run out of votes buy more
    var captchaLoc        = 'input[name="captcha"]';   // Captcha input field
    var captchaTxt        = 'Enter captcha text!';     // Captcha alert text
    var simpatyFormId     = '#sym_send';               // Simpaty window form

    var startScript          = true; 
    var formProcessedAlready = false; // Used to check if image already was voted
    /*######################################################*/  

    $(function(){
        if(startScript){
            if($(captchaLoc).length > 0){
                alert(captchaTxt);
                $(captchaLoc).focus().css('border', '2px solid red');
                return false;
            }else{
                if($('#50').length > 0){
                    $('#50').attr('checked', true);
                    $('form').attr('id', buyExtraVote);
                    $('#'+buyExtraVote).submit();
                }else{
                    $('form').attr('id', voteFormLoc);
                    if($(voteBy).length > 0){
                        $(voteBy).attr('checked', true);
                        setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                    }else if($(voteDefault).length > 0){
                        $(voteDefault).attr('checked', true);
                        setTimeout("$('#"+voteFormLoc+"').submit()", 2000);
                    }else{
                        // If we have simpaty box autocast submit
                        if($(simpatyFormId).length > 0){
                            if($(captchaLoc).length > 0){
                                alert(captchaTxt);
                                $(captchaLoc).focus().css('border', '2px solid red');
                                return false;
                            }else{
                                $(simpatyFormId).submit();
                                formProcessedAlready = true;
                            }
                        }else{
                            formProcessedAlready = true;
                        }
                    }
                }
            }

            if(formProcessedAlready){
                self.close();
            }
        }
    });
}
else
{   //--- This is a main page

    $('form[name="form_gallery"] .img img').each(function(i,e){
        // Format URL array here
        if($(this).closest('.object').children('.phs_voted_count').length == 0){
            var string = e.src;
            var nowBrake = string.substring(string.length-7,7);
            var splited = nowBrake.split('/');
            var urlStr = '/window/friend/gallery_view/'+splited[3]+'/'+splited[4]+'.html';
            URL_Array[i] = urlStr;
        }
    });

    //--- Load up the queue.
    $.each (URL_Array, function (PopupNum, PopupURL) {

        PopupQueue.queue ('Popups', function (NextQ_Item) {

            OpenPopupFromQueue (NextQ_Item, PopupNum+1, PopupURL);
        } );
    } );

    //--- Launch the Popups, one at a time.
    PopupQueue.dequeue ('Popups');
}


function OpenPopupFromQueue (NextQ_Item, PopupNum, PopupURL)
{
    var PopupWin    = window.open (PopupURL, "_blank");
    if (!PopupWin)
    {
        console.log ('Bad URL ' + PopupURL)
        setTimeout (function() { NextQ_Item (); }, 2003);
        return;
    }

    /*--- Only after the popup has loaded can we do any processing.
    */
    PopupWin.addEventListener (
        "load",
        function () {
            /*--- Setup the listener for when the popup has closed.
                We fire the next popup from the queue, there.
            */
            PopupWin.addEventListener (
                "unload",
                function () {
                    PopupClosed (NextQ_Item);
                },
                false
            );

            /*--- We could process the popup here, but it's better to let another instance of this
                script do it, instead.
            */
        },
        false
    );
}


function PopupClosed (NextQ_Item)
{
    //--- Launch the next popup from the queue.
    NextQ_Item ();
}

【讨论】:

  • 啊,布洛克你好。是的,您的脚本看起来不错,但在 chrome 中我只是得到Uncaught TypeError: Cannot call method 'addEventListener' of undefined。我现在使用 1.5.2 版本,并将其粘贴到我的脚本中。主页网址:http://friends.example.com/friend/28r6afk4bf/gallery/3044094.html,我将其与http://friends.example.com/friend/*/gallery/*匹配,弹出窗口为:http://friends.example.com/window/friend/gallery_view/28r6afk4bf/a4w01kb3i0bg.html,我也将其与http://friends.boomtime.lv/window/friend/*匹配
  • 好的,我调整了代码。它现在不应该在错误的 URL 上出错。脚本看起来不错,但后来出错了?这是否意味着它可以在 Firefox 中运行?或者,它适用于一些弹出窗口然后出错?我的测试有效,如果不知道真正的目标页面,我无法进一步调试。
  • 现在它会弹出 1 个窗口并吐入控制台 Bad URL /window/friend/gallery_view/28r6afk4bf/cxa4w065bnz1bg.html。目标页面是什么意思?
  • 目标页面是指在真实服务器上运行脚本的确切页面之一。 ... ... 该错误意味着/window/friend/gallery_view/28r6afk4bf/cxa4w065bnz1bg.html 不是有效页面。这可能是因为主页(又名目标页面)在一个域上,但弹出页面需要在另一个域上。仔细检查生成的URL_Array。您可能需要向每个 URL 字符串显式添加正确的 http://friends.example.com/(或其他)。
  • 错误的 URL http://friends.boomtime.lv/window/friend/gallery_view/cbh5bxbybf/cxd3582a3ukbn.html 这是完整的弹出 URL。仍然 1 弹出,然后以错误的 url 停止。也许用 javascript 用户脚本不可能做到这一点?域是相同的。
【解决方案2】:

你可以这样做:

var links = get_your_links();
function process_one() {
    if(links.length > 0) {
        show_popup(links.pop(), process_one);
    }
}
function show_popup(link, callback) {
   var popup = window.open(link, "mywindow", "width=100,height=100");
   $(popup).bind("beforeunload", function() { 
     process_one();
     return true;
   })

}

希望对你有帮助……

【讨论】:

  • 一切看起来都不错,我让它为第一个弹出窗口工作,但其他弹出窗口不处理。这可能是因为$(window).bind 因为它绑定了当前窗口,而不是弹出窗口,而是主页。我需要点击刷新才能处理其他。怎么像$(popup).bind一样绑定?
  • 仍然只在第一次加载页面时执行。看起来它正在丢失弹出窗口并且无法从中捕获任何事件。我在脚本中的主页和弹出地址都有// @match
  • mmmm,所以 beforeunload 没有触发?你能用firebug调试它吗?
  • 只需获取一个变量,说明 process_one() 是否已经完成,并在 onunload 和函数中添加事件,检查变量是否为真,如果是,请不要做任何事。
  • @iwiznia 我使用 chrome 开发工具栏,但在控制台中什么也没有。如果我要使用 FireFox,我需要将代码改编为greasemonkey。
猜你喜欢
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
相关资源
最近更新 更多