javascript - 如何在循环中打开弹出窗口并相应地执行回调以返回状态? (Greasemonkey 脚本)

标签 javascript jquery greasemonkey

我无法为这个问题制定合适的标题,所以我将在这里描述这个想法/问题。

所以,目前我有 2 个脚本用于任务:

第一个脚本:循环特定网站上的所有图像,如果在我们打开门户提供的投票弹出窗口之前没有对它们进行投票(一次最多 20 张图像)。

第二个脚本:为图片设置投票并提交表单,表单提交后关闭弹出窗口。

这里的问题是一段时间后弹出窗口设置了验证码字段来防止这种情况 :)。 所以真正的问题是:我可以将两个脚本合二为一并在我的循环中等待弹出窗口打开并检查验证码字段是否存在?然后我可以停止循环并告诉用户手动输入验证码并在那之后重新加载页面。目前 (ofc) 脚本只会运行并打开弹出窗口(我如何循环等待弹出窗口打开并加载 DOM)?

呸,真的很难解释,如果需要更多信息请告诉我。

编辑:好的,让我们改变它:如何在循环中打开弹出窗口并等待来自弹出脚本的回调,然后才根据返回状态继续?

所有GM脚本:

// ==UserScript==
// @name           Open image popups and vote
// @namespace      Popuopener
// @description    Open image popups and vote
// @include        http://example.com/friend/*
// @include        http://example.com/window/friend/*
// @require        http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// ==/UserScript==

// Loop options
var start_Script = true;
var loop = 0;

// Photo rating options
var formProcessedAlready = false;

if(start_Script){

    $('form[name="form_gallery"] .img img').each(function(i,e){
        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';
            wondows = window_open(urlStr, 700, 630);
            if(wondows.getElementById("vte_mark_5")){ // Trows me with wondows.getElementById is not a function
                alert("Popup loaded"); // Does not getting so far 
            }else if(wondows.getElementsByName("captcha")[0]){
                alert("Captcha inside");
                return false;
            }
            if($('input[name="captcha"]').length > 0){
                alert('Enter captcha then (F5)!');
                return false;
            }else{
                    if($('#vte_mark_5').length > 0){
                        $('#vte_mark_5').attr('checked', true);
                        $('form[name="popup_form"]').submit();  
                    }else{
                        formProcessedAlready = true;
                    }

                    if(formProcessedAlready){
                        window.close();
                    }
            }
        }else{
            loop++;
        }
        alert("End");
    }

}

function window_open(url, width, height, name, scroll_bar, location){

    _top = Math.ceil((screen.height - height)/2);
    _left = Math.ceil((screen.width - width)/2);

    if(scroll_bar != true){
        var scroll = 'no';
    }else{
        var scroll = 'yes';
    }
    if(typeof location != "undefined" && location == true){
        var location = 'yes';
    }else{
        var location = 'no';
    }

    if(name == undefined){
        name = Math.round(999999 * Math.random());
    }
    return window.open(url, name , 'width=' + width + ',height=' + height + ',location='+ location +',status=no,toolbar=no,menubar=no,resizable=yes,scrollbars=' + scroll + ',top=' + _top + ',left=' + _left);
}

最佳答案

弹出窗口异步加载和关闭,因此“wondows.getElementById("vte_mark_5")”之类的东西不会立即起作用。您需要等待弹出窗口的加载事件。

在 Greasemonkey 中,您可以使用类似这样的东西:PopupWin.addEventListener("load",...) (与 onload=... 相比,这是最佳实践。)

同样,普通循环只会一次打开所有弹出窗口。要按顺序打开弹出窗口,请使用队列。由于您已经在使用 jQuery,请切换到版本 1.5.1 以使用 jQuery's queue functions .
请注意,从 GM 版本 0.9 开始,Greasemonkey 可与 jQuery 1.5.1 一起使用。

~~~
假设您有一个弹出 URL 数组...

var URL_Array   = [ "http://jsbin.com/omuvu5/#111",
                    "http://jsbin.com/omuvu5/#222",
                    "http://jsbin.com/omuvu5/#333"
                ];

然后你可以建立一个队列:

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

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

    PopupQueue.queue ('Popups', function (NextQ_Item) {
        OpenPopupFromQueue (NextQ_Item, PopupNum+1, PopupURL);
    } );
} );


OpenPopupFromQueue打开一个弹出窗口并设置打开和关闭事件处理程序...

function OpenPopupFromQueue (NextQ_Item, PopupNum, PopupURL)
{
    var PopupWin    = window.open (PopupURL, "_blank");

    /*--- Only after the popup has loaded can we do any processing.
        See PopupMain() for examples of manipulation via jQuery.
    */
    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
            );

            //--- Now process the popup, as desired.
            PopupMain (PopupWin, PopupNum);
        },
        false
    );
}


加载事件处理程序显示了如何使用主页 (GM) 的 jQuery 操作弹出窗口...

function PopupMain (PopupWin, PopupNum)
{
    //--- This manipulates the main window.
    $("#PopupStatus").append ("<li>Popup Loaded.</li>");

    //--- This manipulates the popup window.
    $("#PayloadTarget", PopupWin.document).prepend ('<h3>This is popup number: ' + PopupNum + '.</h3>');
}


关闭事件处理程序必须触发队列中的下一个项目...

function PopupClosed (NextQ_Item)
{
    NextQ_Item ();
}


最后,您使用以下命令关闭队列:

PopupQueue.dequeue ('Popups');


可以看到a demo that puts it all together at jsBin.com .

关于javascript - 如何在循环中打开弹出窗口并相应地执行回调以返回状态? (Greasemonkey 脚本),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5520186/

相关文章:

javascript - 用元素替换字符串

javascript - 单击时突出显示或向父 li 元素添加类

javascript - 在 Highchart 堆栈列总计中鼠标悬停时显示工具提示

javascript - 让 Greasemonkey 对元素的 ajax 更改使用react

javascript - Stripe with Rails 捐款

javascript - 使用 $(this) 的 Jquery 选项

javascript - 如何增加span元素内的文本

Javascript如何根据href更改 anchor 背景颜色

javascript:站点将对象传递给 setinterval

javascript - 如何使用我添加的外部脚本来 react JS?