【问题标题】:jQuery .each() and ajax to get sizejQuery .each() 和 ajax 获取大小
【发布时间】:2013-01-12 18:24:44
【问题描述】:

我有 php 文件中的地址列表,这些文件按国家/地区标记。因此,在一个名为 uk 的列表中,我可以有 12 个地址列表项。但是在我的主页上,我尝试使用 jQuery 来计算每个国家/地区的值,然后将值放在该国家/地区地图上的 div 中,以便它表明 uk 是 x 个地址,usa 有 x 个地址等等。

我在下面整理的代码一直有效到 .ajax,然后在 console.log 中它回显 1 个国家而不是国家列表。

HTML

<div class="right map">
    <div class="canada" data-name="Canada"></div>
    <div class="usa" data-name="USA"></div>
    <div class="uk" data-name="UK"></div>
    <div class="ireland" data-name="Ireland"></div>
    <div class="spain" data-name="Spain"></div>
    <div class="portugal" data-name="Portugal"></div>
    <div class="italy" data-name="Italy"></div>
    <div class="australia" data-name="Australia"></div>
</div>

jQuery

$('.map div').each(function() { 
    $this = $(this);
    country = $this.attr("class");
    console.log(country);
    $.ajax({
        url : "/assets/inc/coe/"+country+".php",
            success : function (data) {
                console.log($('.map div.'+country));
                $('.map div.'+country).text($(data).find('li').size());
            }
        }); 
});

php 文件

<ul>
    <li>
        <strong>Company Name</strong>
        123 Fake Street<br />
        Fakesville<br />
        <a href="#">Link</a>
    </li>
    <li>
        <strong>Company Name</strong>
        123 Fake Street<br />
        Fakesville<br />
        <a href="#">Link</a>
    </li>
</ul>

console.log

canada
usa
uk
ireland
spain
portugal
italy
australia
[div.australia]
[div.australia]
[div.australia]
[div.australia]
[div.australia]
[div.australia]
[div.australia]
[div.australia]

【问题讨论】:

    标签: javascript jquery ajax closures each


    【解决方案1】:

    使您的 ajax 请求同步。添加async: false 将起作用。它将等待当前的 ajax 请求完成,然后再开始另一个。所以对country 的引用将正确映射到正确的国家div

    $('.map div').each(function() { 
    $this = $(this);
    country = $this.attr("class");
    console.log(country);
    $.ajax({
        url : "/assets/inc/coe/"+country+".php",
        async: false,
            success : function (data) {
                console.log($('.map div.'+country));
                $('.map div.'+country).text($(data).find('li').size());
            }
        }); 
    

    });

    【讨论】:

    • @DonaldSutherland:虽然这个解决方案应该可以工作,但请注意,在设置 async: false 时,您的 UI 将在每个单独的请求期间锁定。如果一个请求需要一点时间,用户可能会觉得浏览器被冻结了。
    • @DonaldSutherland Elliot B 回答会更好
    【解决方案2】:

    您遇到的问题是 country 不在您的 success 函数的范围内。当您的success 函数被调用时,它会查找作用域链以找到country。但是因为您的 AJAX 是异步运行的,所以循环将始终在调用 success 之前完成,因此 country始终成为循环中设置的最后一个国家/地区。

    要解决此问题,您需要将success 函数嵌套在新的作用域级别中,并按值传递country。在下面的示例中,我通过一个立即执行的函数来实现这一点,该函数返回您原来的 success 函数:

    改变这个:

    $.ajax({
            url : "/assets/inc/coe/"+country+".php",
                success : function (data) {
                    console.log($('.map div.'+country));
                    $('.map div.'+country).text($(data).find('li').size());
                }
            }); 
    

    到这里:

    $.ajax({
            url : "/assets/inc/coe/"+country+".php",
                success : (function (country) {
                    return function(data) {
                        console.log($('.map div.'+country));
                        $('.map div.'+country).text($(data).find('li').size());
                    };
                })(country)
            }); 
    

    都是关于closures

    【讨论】:

      【解决方案3】:

      这是一个闭包问题和ajax的异步;它有一个国家变量的句柄,它击败了所有的 ajax 调用,所以它总是在最后一个设置(澳大利亚)。

      向 ajax 函数/对象写入新属性

      $.ajax({
              url : "/assets/inc/coe/"+country+".php",
              country: country,
                  success : function (data) {
                      var country = this.country;
                      console.log($('.map div.'+country));
                      $('.map div.'+country).text($(data).find('li').size());
      
                  }
              }); 
      

      【讨论】:

        猜你喜欢
        • 2014-11-13
        • 2011-01-03
        • 1970-01-01
        • 2014-11-20
        • 2013-02-12
        • 2013-07-01
        • 1970-01-01
        • 2010-12-05
        • 2013-06-29
        相关资源
        最近更新 更多