【问题标题】:.click() callback references local variable from the calling method instead of copying by value.click() 回调从调用方法引用局部变量,而不是按值复制
【发布时间】:2011-02-16 23:48:50
【问题描述】:

以下 jQuery Javascript 代码包含在原本为空的页面中。

var element;
$(function() {
  for (var i = 0; i < 10; i++) {
    element = $('<div>' + i + '</div>');
    element.click(function() {
      alert(i);
    });
    $('body').append(element);
  }
});

期望的行为是这段代码应该生成 10 个 div 元素,编号从 0 到 9。当你点击一个 div 元素时,一个警告弹出窗口将显示你点击的 div 元素的编号(即,如果用户点击标记为“4”的 div 元素,警报弹出窗口应显示数字 4)。

无论单击哪个 div 元素,警报弹出窗口都会显示数字 10。

如何修改此代码以使其以所需的方式运行?

【问题讨论】:

  • 结果是 10 并且总是 10,因为 i 是一个在你的 for 循环中迭代的 var。由于i++,它在循环结束时结束于10。您的问题更多是关于从单击的 div 中提取有用的数字,还是为什么 i 在将函数传递给事件处理程序时会这样?

标签: javascript jquery pass-by-reference pass-by-value


【解决方案1】:

您需要将变量作为函数参数传递。

例如:

function buildElement(i) {
    var element = $('<div>' + i + '</div>');
    element.click(function() {
        alert(i);
    });
    $('body').append(element);
}

$(function() {
    for (var i = 0; i < 10; i++) {
        buildElement(i);
    }
});

您也可以使用内联匿名函数执行此操作,如下所示:

$(function() {
    for (var i = 0; i < 10; i++) {
        (function(i) {
            var element = $('<div>' + i + '</div>');
            element.click(function() {
                alert(i);
            });
            $('body').append(element);
        })(i);
    }
});

【讨论】:

  • +1 正确使用闭包并像其他答案一样绕过它。但这应该是var element = ...
【解决方案2】:

你可以做两件事中的一件。您可以使用 div 的内容来输出 is,或者您可以从选择器中获取数组中的索引。

这是一个内容示例:

element.click(function() {
  alert($(this).text());
});

或者对于索引:

element.click(function() {
  alert($('div').index(this));
});

我相信两者都应该工作

【讨论】:

  • 虽然这看起来可行,但这忽略了正确使用闭包的真实而简单的问题。
  • 问题不在于如何使用闭包。我认为提供解决所提问题的其他解决方案没有问题。
  • 你是对的,问题不在于如何使用闭包,而是闭包是合适的答案,并使用设计的语言。不必要地访问 DOM 就是:没有必要。
【解决方案3】:

通常我将数字隐藏在 id 中,然后以某种结构化的方式将其取出:

$(function() {
    for (var i = 0; i < 10; i++) {
        element = $('<div id="id-'+i+'">' + i + '</div>');
        element.click(function() {
            alert($(this).attr('id').split('-')[1]);
        });
        $('body').append(element);
    }
});

【讨论】:

  • 这里真正的问题是没有使用闭包。请参阅 SLaks 的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-01
  • 2015-12-06
  • 2012-06-27
  • 2012-12-19
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
相关资源
最近更新 更多