【问题标题】:Increment counter unavailable outside of loop增量计数器在循环外不可用
【发布时间】:2010-12-22 02:26:53
【问题描述】:

我正在使用 jQuery 的 $.each() 循环遍历 json 返回值,并将返回的类添加到它们对应的 <div>'s;但是,计数器似乎无法在立即循环之外进行进一步处理。我尝试使用 return 和外部函数调用无济于事。当我 alert() 迭代内的计数器时,它会正确显示;并且所有类都正确更新。任何见解将不胜感激。

代码:

var c = 0;
function refreshIt(){
  var page = $(".navselected").attr('id');
  var ids = $('.content div[id]').map(function(){
    return this.id;
  }).get();

  $.ajax({
    type:'POST',
    url:page + 'functions.php',
    data:{'idList[]':ids},
    dataType:'json',
    success:function(data){
      $.each(data,function(element,load){
        $("#" + element).slideUp(400,function(){
          $("#" + element).removeClass("critical ok");
          $("#" + element).addClass(load.status).html(load.number).slideDown(400);
          if(load.status == 'ok'){
            c++;
          }
          else{
            c++;
          }
        });
      });

      $('.infostatus').addClass('infook').html("There are " + c  + " errors on this page.     Kudos!");
    }
  });
}

【问题讨论】:

  • 这是一个范围问题。该变量在循环之外的任何地方都不“存在”。我不确定要推荐什么,因为我不太了解 jQuery 的 $.each 背后发生了什么
  • @jon_darkstar:不正确,var 是脚本的第一行,在所有代码块之外。

标签: javascript jquery


【解决方案1】:

当您进行 ajax 调用时,浏览器会发送请求并将函数附加到它,然后在等待响应的同时继续执行脚本的其余部分。这意味着最后一行代码几乎肯定会在 ajax 返回之前执行。将该行放在 ajax 成功函数中,就在每个函数之后:

$.ajax({
  type:'POST',
  url:page + 'functions.php',
  data:{'idList[]':ids},
  dataType:'json',
  success:function(data){
    $.each(data,function(element,load){
    $("#" + element).slideUp(400,function(){
    $("#" + element).removeClass("critical ok");
    $("#" + element).addClass(load.status).html(load.number).slideDown(400);
    if(load.status == 'ok'){
      c++;
    }
    else{
      c++;
    }
  });

  $('.infostatus').addClass('infook')
  .html("There are " + c  + " errors on this page.     Kudos!");

});

【讨论】:

  • 感谢您的快速响应和相应的解释;非常感激。经过测试和验证。
【解决方案2】:

这段代码似乎有更多的{ 括号而不是} 括号,所以很难确定——但我猜问题是你调用.ajax() 然后立即填写HTML致电.html()

.ajax() 方法只触发请求;它不会等到收到响应。因此,您的.html() 调用正在执行响应返回并处理数据之前。

要解决此问题,只需将最后两行代码移动到 success 函数中,紧接在调用 .each() 之后。

【讨论】:

  • 大括号不匹配是我的错。很抱歉,我错过了一些带有左括号的内部声明。
  • @Brad:酷。您问题中的更新代码看起来应该可以工作。还是不行?
【解决方案3】:

目的是什么

if(load.status == 'ok'){
  c++;
}
else{
  c++;
}

这是您的简化代码:

var c = 0;
function refreshIt() {
    var page, ids;
    page = $(".navselected").attr('id');
    ids = $('.content div[id]').map(function() {
        return this.id;
    }).get();

    $.ajax({
        type:'POST',
        url:page + 'functions.php',
        data:{'idList[]':ids},
        dataType:'json',
        success:function(data){
            $.each(data,function(element,load){
                var elem = $("#" + element);
                elem.slideUp(400,function() {
                    elem.removeClass("critical ok");
                    elem.addClass(load.status).html(load.number).slideDown(400);
                    c++;
                });
            });
            $('.infostatus').addClass('infook')
                .html("There are " + c  + " errors on this page.     Kudos!");
        }
    });
}

【讨论】:

  • 感谢有关简化代码的提示。在无法获得工作条件后,我尝试了各种方式让柜台的任何通信都通过;多余的 if...else 是残留的,已被删除。
猜你喜欢
  • 2019-03-12
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 2019-04-28
  • 2017-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多