Очередь jQuery в пользовательском скрипте Chrome с всплывающими окнами?

Я хотел бы спросить, возможно ли создать скрипт 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) Получить все URL-адреса, за которые не проголосовали, и сформировать массив (готово)
2) Поставить все всплывающие окна в очередь для открытия
3) Запустить первое всплывающее окно
4) Голосование завершено, всплывающее окно закрывается (готово)
5) Запустить второе всплывающее окно
6) По завершении массива перейти к следующему страница (готово)

Что думаешь?


person arma    schedule 24.04.2011    source источник
comment
Лучше сделать это одним всплывающим окном, чтобы ни одна антивирусная программа не заблокировала его. Запустить первое всплывающее окно -> Голосование завершено, и всплывающее окно обновится с новой формой -> ...   -  person Arthur Halma    schedule 26.04.2011
comment
Я за любое решение, одно или новое каждый раз. Я буду единственным человеком, который будет использовать это, поэтому я не беспокоюсь о какой-либо блокировке.   -  person arma    schedule 27.04.2011


Ответы (2)


  • Каковы точные URL-адреса главной страницы (страниц), а также всплывающих окон?
  • Какую версию jQuery вы используете и как вы ее включаете?

Точные URL-адреса важны, потому что скрипт должен обрабатывать как главные страницы, так и всплывающие окна, и работать с ними по-разному.

Их 2 основных способа справиться с этим. Либо:

  1. Используйте директивы include, чтобы убедиться, что скрипт работает как на главной странице, так и во всплывающем окне, но меняет свое поведение в зависимости от типа страницы. Это будет иметь два разных экземпляра сценария, работающих одновременно, что не является проблемой.

  2. Используйте директивы include и, возможно, exclude, чтобы скрипт выполнялся только на главной странице. Затем пусть код открытия всплывающего окна манипулирует формой.


Вот как сделать подход 1:

(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 ();
}
person Brock Adams    schedule 01.05.2011
comment
А, Брок привет. Да, ваш скрипт выглядел хорошо, но в Chrome я просто получаю Uncaught TypeError: Cannot call method 'addEventListener' of undefined. Сейчас я использую версию 1.5.2, и я вставил ее в свой скрипт. URL-адрес главной страницы: 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/* - person arma; 02.05.2011
comment
Хорошо, я подправил код. Теперь он не должен выдавать ошибки на неверных URL-адресах. Сценарий выглядел хорошо, но потом выдал ошибку? Означает ли это, что он работал в Firefox? Или это работало для нескольких всплывающих окон, а затем выдавало ошибку? Мои тесты работают, я не могу дальше отлаживать, не зная реальной целевой страницы. - person Brock Adams; 02.05.2011
comment
Теперь он делает 1 всплывающее окно и выплевывает в консоль Bad URL /window/friend/gallery_view/28r6afk4bf/cxa4w065bnz1bg.html. Что вы подразумеваете под целевой страницей? - person arma; 02.05.2011
comment
Под целевой страницей я подразумеваю одну из точных страниц на реальном сервере, на которой выполняется скрипт. ... ... Эта ошибка означает, что /window/friend/gallery_view/28r6afk4bf/cxa4w065bnz1bg.html не является допустимой страницей. Это может происходить из-за того, что главная страница (также известная как целевая страница) находится в одном домене, а всплывающая страница должна быть в другом. Внимательно изучите сгенерированный URL_Array. Возможно, вам придется явно добавить правильный http://friends.example.com/ (или что-то еще) в каждую строку URL. - person Brock Adams; 02.05.2011
comment
Неверный URL http://friends.boomtime.lv/window/friend/gallery_view/cbh5bxbybf/cxd3582a3ukbn.html здесь полный URL всплывающего окна. Тем не менее 1 всплывает, а затем останавливается с неверным URL. Может быть, это невозможно сделать с помощью пользовательских скриптов javascript? домены одинаковые. - person arma; 02.05.2011
comment
Это возможно; В любом случае, я тестировал его с FF GM (и нет очевидной причины, по которой Chrome должен отличаться в этом случае). Во всяком случае, я изменил код, чтобы он продолжал работу после сбоя. ... ... Вы говорите, что все еще 1 всплывает, а затем останавливается с неверным URL-адресом. Открывается ли 1 всплывающее окно, затем закрывается, а затем отображается неверный URL-адрес? неверный URL-адрес совпадает с открытым всплывающим окном? ... ... Наконец, посмотрите на URL в вашем последнем комментарии. кажется, что он заканчивается на .html, но если вы посмотрите на реальный код, это .-html. Это была просто ошибка вставки? - person Brock Adams; 02.05.2011
comment
1) Когда всплывающее окно открывается - оно выполняет все необходимые действия (помещает голос в нужное поле и отправляет его через 2000 мс и в то же время выдает запись консоли BadUrl. 2) -.html должно быть ошибка вставки или что-то в этом роде, потому что у меня нет этого нигде в моем коде. 3) Ваш последний обновленный код открывает сразу все попапы (их 20) и обрабатывает их по желанию, но получает бан антиспама из-за слишком быстрого голосования. - person arma; 03.05.2011
comment
Что-то на сайте или в вашей фактической настройке нарушает функциональность window.open(). Он не устанавливает возвращаемое значение. Мой локальный тестовый сайт работает нормально. ... ... Во всяком случае, я добавил 2-секундную задержку в случае сбоя в модифицированный код выше. Если антиспам-бан по-прежнему срабатывает, увеличьте задержку. Из соображений скрытности я рекомендую использовать простое число и минимум 1 секунду. - person Brock Adams; 03.05.2011
comment
Ну, я думаю, это самое близкое, что я могу сделать для автоматизации этого. Не безотказно, но сойдет. Просто добавим переключение страниц и будет ок. Спасибо за все ваши усилия. - person arma; 03.05.2011
comment
Что ж, я рад, что это, наконец, сработало для вас. Мы приближались к пределу отладки, которую я мог выполнить без доступа к страницам, которые вы используете. - person Brock Adams; 03.05.2011
comment
Да, я понимаю, что это не торт для вас. Мне удалось удалить cookie, который следит за таймерами капчи, и с тайм-аутом 3003 мс я могу оставить это автоматически :) - person arma; 03.05.2011

Вы можете сделать что-то вроде:

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;
   })

}

Я надеюсь, что это помогает...

person iwiznia    schedule 26.04.2011
comment
все выглядит хорошо, и у меня это работает для первого всплывающего окна, но другие всплывающие окна не обрабатываются. Это, вероятно, потому, что $(window).bind связывает текущее окно, которое является не всплывающим, а главной страницей. мне нужно нажать «Обновить», чтобы другие были обработаны. Как вы связываете это как $(popup).bind ? - person arma; 27.04.2011
comment
По-прежнему выполняется только при первой загрузке страницы. Похоже, он теряет всплывающее окно и не может поймать какие-либо события из него. У меня есть // @match как для главной страницы, так и для всплывающего адреса в сценарии. - person arma; 28.04.2011
comment
мммм, значит, перед выгрузкой не срабатывает? Можете ли вы отладить его с помощью firebug? - person iwiznia; 28.04.2011
comment
Просто получите переменную, указывающую, что process_one() уже был выполнен, и добавьте событие onunload также и в функцию, проверьте, является ли переменная истинной или нет, и если это так, просто ничего не делайте. - person xavierm02; 28.04.2011
comment
@iwiznia я использую панель инструментов chrome dev и ничего не получаю в консоли. Если бы я перешел на FireFox, мне нужно было бы адаптировать код для Greasemonkey. - person arma; 29.04.2011