【问题标题】:Event doesn't get added in a for-loop事件未在 for 循环中添加
【发布时间】:2011-06-13 15:33:00
【问题描述】:

这是html。如果单击链接,我想用一些文本替换它前面的跨度元素。

<p><span id="sp1">that1</span> <a href="#" id="update1">Update1</a></p>
<p><span id="sp2">that2</span> <a href="#" id="update2">Update2</a></p>
<p><span id="sp3">that3</span> <a href="#" id="update3">Update3</a></p>
<p><span id="sp4">that4</span> <a href="#" id="update4">Update4</a></p>
<p><span id="sp5">that5</span> <a href="#" id="update5">Update5</a></p>

如您所见,我的想法是为锚点中的跨度提供相同的 id 和一个数字。

在我的 jquery 代码中,我遍历所有锚元素,给它们一个点击事件,导致它前面的跨度元素被替换。

<script type="text/javascript" >

  $(document).ready(function() {
   var numSpans = $("span").length;
   for (n=0;n<=numSpans;n++) {
     $("a#update" + n).click(function(e){
       $('span#sp' + n).replaceWith('this');
       e.preventDefault();
     });    
   }   
  });

</script>

由于某种原因,这不起作用。

我做错了什么?

【问题讨论】:

  • @zod 这是解决方案的一部分,但只是这样的链接并不是那么有用(除非您已经知道答案)。
  • @Matt 对新用户肯定有用。别担心
  • 这里的问题是闭包问题,不是事件绑定问题
  • @Eric 但问题已通过使用不同的事件绑定范例得到解决。
  • @zod 感谢您的链接。我只是涉足 jQuery,每一个新的信息都非常受欢迎!

标签: javascript jquery for-loop


【解决方案1】:

您的原始代码的问题在于您正在对变量n 创建一个闭包。调用事件处理程序时,在调用点而不是声明点使用 n 的值调用它。您可以通过添加警报调用来看到这一点:

$(document).ready(function() {
    var numSpans = $("span").length;
    for (n = 1; n <= numSpans; n++) {
        $("a#update" + n).click(function(e) {
            alert(n); //Alerts '6'
            $('span#sp' + n).replaceWith('this');
            e.preventDefault();
        });
    }
})

解决此问题的一种方法是在每次迭代中对 n 的值创建一个闭包,如下所示:

$(document).ready(function() {
    var numSpans = $("span").length;
    for (n = 1; n <= numSpans; n++) {
        $("a#update" + n).click(
            (function(k) {
                return function(e) {
                    alert(k);
                    $('span#sp' + k).replaceWith('this');
                    e.preventDefault();
                }
            })(n)
        );
    }
})

但是,这很麻烦,您最好使用更加 jQuery-y 的方法。


一种方法是从您的代码中删除ids。除非您需要它们用于其他用途,否则它们不是必需的:

<p><span>that1</span> <a href="#" class="update">Update1</a></p>
<p><span>that2</span> <a href="#" class="update">Update2</a></p>
<p><span>that3</span> <a href="#" class="update">Update3</a></p>
<p><span>that4</span> <a href="#" class="update">Update4</a></p>
<p><span>that5</span> <a href="#" class="update">Update5</a></p>

jQuery:

$(function() {
    $('a.update').live('click', function() {
        $(this).siblings('span').replaceWith("Updated that!");
    });
});

jsFiddle

【讨论】:

  • 有趣!这看起来像是我必须经常考虑的事情。谢谢你的解释。
【解决方案2】:

不要在循环中创建函数。使用 jQuery,根本不需要显式循环。

$(function()
{
    $('span[id^=sp]').each(function(n)
    {
        $('#update' + n).click(function(e)
        {
            $('#sp' + n).replaceWith(this);
            return false;
        });
    });
});

演示:http://jsfiddle.net/mattball/4TVMa/


不过,方式你可以做得更好:

$(function()
{
    $('p > a[id^=update]').live('click', function(e)
    {
        $(this).prev().replaceWith(this);
        return false;
    });
});

演示:http://jsfiddle.net/mattball/xySGW/

【讨论】:

  • 感谢您的代码。第一个在我使用的实际代码中效果很好。但第二个看起来更干净。我将进一步深入研究。
【解决方案3】:

试试这个:

$(function(){
    $("a[id^='update']").click(function(){
        var index = this.id.replace(/[^0-9]/g, "");
        $("span#sp" + index).replaceWith(this);
        e.preventDefault();
    });
});

【讨论】:

    猜你喜欢
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多