【问题标题】:Losing selector after $.get in jquery在 jquery 中 $.get 后丢失选择器
【发布时间】:2011-11-02 15:02:18
【问题描述】:

我阅读了页面上的所有<li>,通过Ajax 向其他页面提交请求。都很好。

我遇到的唯一问题是在请求返回后更新<li>。在$.get$li$(this) 之外是当前的<li>。在$.get 内,$li 始终是页面上的最后一个<li>,这是我的问题。

//For each <li>
$('ul#clients li').each(function(index) {
    $li = $(this);
    $li.append('This is ok');

    //Update Data via Ajax
    $.get("/ajax-update.php", function(data) {  $li.append('This is not OK!'); });

}           

【问题讨论】:

  • 这是一个范围问题 - $li 未在您的匿名函数的范围内定义...
  • nitpick: 把你的选择器改成#clients li,ID前的ul是不必要的
  • jbabey - 如果 javascript 在不同的页面上共享(有时是这种情况),那么如果您在另一个页面上有另一个带有 id=clients 的元素,如果您这样做,它可能会导致问题。加上这样做的好习惯,彻底没有错。
  • @ThomasClayson 彻底有问题,那就是性能损失。事实上,只要考虑性能,最好的写法是$('#clients').find('li')
  • Akkuma 在$('ul#clients')$('#clients') 之间是否存在性能损失。我原以为将选择器缩小到仅uls 会提高性能?

标签: javascript jquery closures


【解决方案1】:

使用var... 如果没有var 前缀,将在声明$li 的最近父范围内定义一个变量。如果 $li 从未被声明过,它将在全局 (window) 范围内定义。

//For each <li>
$('ul#clients li').each(function(index) {
    var $li = $(this);
    $li.append('This is ok');

    //Update Data via Ajax
    $.get("/ajax-update.php", function(data) {  $li.append('This is not OK!'); });

}           

【讨论】:

  • @DaveNewton 不,不是。看看我回答的前两句话。
  • 嗯,刷新前没看到这两句话。
  • 不确定是否使用全局变量从而污染全局范围是最好的解决方案
  • @FernandoDiazGarrido 我的答案中没有看到任何全局变量声明。但是,在您的回答中,我看到 $li 成为一个全局变量。
【解决方案2】:

这里的问题是 $.get 是异步的。这意味着它在单独的线程上运行。因此,在该线程完成之前,它已经通过其他 li 运行,并且每次更改 $li 变量。

所以当所有的 $.get 在最后一个 $li 上返回它时,这就是为什么你只看到最后一个 li 发生变化。

我认为你可以使用var。这应该将变量的范围限制为当前循环并解决问题。

否则,您可能需要在每个变量之外包含一个计数变量,并使用一个数组来存储 li 对象。如果您需要更多有关这方面的信息,请告诉我。

【讨论】:

    【解决方案3】:

    您可以使用 context 参数来指定回调的上下文。注意这仅在ajax方法中可用,对get不可用,但结果是一样的

    $('ul#clients li').each(function(index) {
      $li = $(this);
      $li.append('This is ok');
    
      $.ajax({
        url: "/ajax-update.php",
        context: this,
        success: function(){
          $(this).append('This is not OK!');
        }
      });
    }
    

    【讨论】:

    • 我个人认为这是在回避一个严重的问题,创建一个可能不是全局的全局变量。
    • @Akkuma 在我的示例中没有全局变量,我只是传递上下文,所有其他答案都建议使用全局变量,但我的
    • $li 在您的示例中如何不在全局上下文中?是的,您将 ajax 绑定到上下文并解决了问题,但您仍在创建全局变量。 Rob W 和我都同意这一点。其他示例均不建议使用全局变量。
    • 非常正确,我从复制/粘贴中跳过了这一点,该方法仍然没有使用全局范围,仍然可以将 li 作为局部变量使用
    【解决方案4】:

    以下是您的问题的示例以及如何解决问题的评论:http://jsfiddle.net/Akkuma/AJnR4/

    发生的事情是您的$li 是在全局范围内创建的。由于$.get 是异步的,您的$li 的值设置为第一个$.get 甚至返回成功函数之前的最后一个值。您可以将其视为竞争条件。如果$.get 如此之快以至于它在循环的下一次迭代之前执行,你实际上不会知道这个问题的存在。

    如评论所示,简单的解决方案是将 $li 更改为 var $li 以保持其正确范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-30
      • 2019-02-27
      • 2011-12-19
      • 2011-03-05
      相关资源
      最近更新 更多