$ .each不更新css宽度

时间:2014-09-24 18:41:32

标签: javascript jquery html css

所以我有一个循环,它在每次迭代时执行ajax调用,我想设置更新的进度条..但它没有更新,它在结束时直接变为100%...

我试图将条形更新调用置于成功操作之外(直接在循环内),但它不起作用..

$('button.page').on('click', function(e){
    var $userList = textArray($('#page-userlist').val().replace('http://lop/', '').split(/\n/));
    var $proxyList = textArray($('#page-proxylist').val().replace('http://', '').split(/\n/));
    var $question = $('#page-question').val();
    var data = {
        question: $question,
        users: $userList,
        proxies: $proxyList
    };
    var i = 0, p = 0, max = data.proxies.length, totalusers = data.users.length, percent = 0;
    $('#log').append("\n" + moment().calendar() + "\n");
    var progressbar = $('#page-progress');
    $.each(data.users, function(k, u){
        if(typeof(p) !== 'undefined' && p !== null && p > 0)
        {
            if(i % 10 == 0 && i > 1) p++;
            if(p == max) return false;
        }
        var proxy = data.proxies[p];
        percent = Math.round((i / totalusers) * 100);
        $.ajax({
            type: "POST",
            url: Routing.generate('viral_admin_bot_page'),
            data: {question: $question, user: u, proxy: proxy},
            success: function(result) {
                $('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
                $(progressbar).width(percent + "%");
            },
            error: function(error) {
                $('#log').append(error);
            }
        });


        i++;
    });
});

如果我console.log(percent);它会在每次迭代时完美更新,所以我不知道问题出在哪里。

这是我的代码(没有ajax调用,因为它不是问题)http://jsfiddle.net/dvo1dm03/20/

它将输出到控制台的百分比,目标是将条形更新为每个循环中完成的百分比,因此它进入"实时"带循环。

5 个答案:

答案 0 :(得分:1)

好的,这里是如何做到异步的。

var speed = 75;
var number_of_calls_returned = 0;  // add number_of_calls_returned++ in your ajax success function
var number_of_total_calls;
var loaded = false;

function processUserData(){
    if( number_of_calls_returned < number_of_total_calls){
        setTimeout(function(){processUserData();}, 200);
    }
    else{
        //received all data
        // set progressbar to 100% width
        loaded = true;
        $("#page-progress").animate({width: "100%"},500);
        $("#page-proxylist").val("Received data");
    }
}

function updateProgress(percent, obj){
    setTimeout(function(x){
        if(!loaded)
        $(obj).width(x + "%");
    }, percent*speed, percent);  
}


$('button.page').on('click', function (e) {
    var $userList = textArray($('#page-userlist').val().replace('http://lop/', '').split(/\n/));
    var $proxyList = textArray($('#page-proxylist').val().replace('http://', '').split(/\n/));
    var $question = $('#page-question').val();
    var data = {
        question: $question,
        users: $userList,
        proxies: $proxyList
    };
    var i = 0,
        p = 0,
        max = data.proxies.length,
        totalusers = data.users.length,
        percent = 0;
    //$('#log').append("\n" + moment().calendar() + "\n");
    var progressbar = $('#page-progress');

    number_of_total_calls = totalusers;
    $.each(data.users, function (k, u) {
        if (typeof (p) !== 'undefined' && p !== null && p > 0) {
            if (i % 10 == 0 && i > 1) p++;
            if (p == max) return false;
        }
        var proxy = data.proxies[p];
        percent = (i / totalusers) * 100;  //much smoother if not int
        updateProgress(percent, progressbar);
        i++;
        // simulate ajax call
        setTimeout(function(){number_of_calls_returned++;}, Math.random()*2000);
    });

    //callback function
    setTimeout(function(){processUserData();}, 200);  
});

var textArray = function (lines) {
    var texts = []
    for (var i = 0; i < lines.length; i++) {
        // only push this line if it contains a non whitespace character.
        if (/\S/.test(lines[i])) {
            texts.push($.trim(lines[i]));
        }
    }

    return texts;
}

在这里查看! jsFiddle(非常酷!)

答案 1 :(得分:1)

您的问题是因为您的成功函数有一个闭包,并且每个成功函数都共享相同的percent变量。你可以像这样解决它:

success: function(percent, result) {
    $('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
    $(progressbar).width(percent + "%");
}.bind(percent),

你需要shim bind在旧版浏览器中,或者像这样,这有点丑陋,但应该在没有垫片的情况下在任何地方工作:

success: (function(percent) { return function(result) {
    $('#log').append("\nAtacado usuario " + u + " con proxy: " + proxy + "\n");
    $(progressbar).width(percent + "%");
}; }( percent ),

答案 2 :(得分:0)

如果你想要的是随着AJAX调用的每次成功都增加更新栏我建议一个更简单的解决方案(为了清楚起见,我简化了js代码):

$('button').click(function (e) {
    var i = 0,
        cont = 0,
        totalusers = 100,
        percent = 0;
    var progressbar = $('#page-progress');

    for (; i < totalusers; i++) {
        $.ajax({
            type: "POST",
            url: '/echo/json/',
            data: {
                question: 'something',
                user: 1,
                proxy: 2
            },
            success: function (result) {
                cont += 1;
                percent = Math.round((cont / totalusers) * 100);
                progressbar.width(percent + "%");
            },
            error: function (error) {
                $('#log').append(error);
            }
        });
    };
});

您可以在此fiddle中看到它的实际效果。

希望这有助于或至少为您提供一些想法。

答案 3 :(得分:-1)

我想建议尝试制作一个不依赖帖子的自包含示例,以便您或我们更容易解决问题

同样,您可以控制日志元素,以便您可以尝试记录progressbar元素,百分比和ajax请求的响应

(此代码用于替换fiddler的javascript部分)

var i = 0;
moveProgress();
function moveProgress(){
    if(i < 10000)
    {
        setTimeout(function(){
            $('#page-progress').width((i / 1000) * 100); 
              moveProgress();
        },2);
        i++;
    }
}

它不起作用的原因是因为循环运行速度太快以至于在脚本加载它时加载了它,超时允许你稍微延迟执行(虽然不一定建议使用因为潜在的线程问题。

答案 4 :(得分:-1)

使用setTimeout方法更新进度条。

它将等待一段时间,然后更新进度条的宽度。

myVar = setTimeout("javascript function",milliseconds);

谢谢, Ganesh Shirsat