jQuery .append():奇怪的行为

时间:2013-09-01 12:14:23

标签: jquery dom append

我使用jQuery的.append()方法面临一种奇怪的行为。

var container = $('#container');


var buttons = {
    'Okay': function() {
        return 'Yeah, I\'m okay with this.';
    },
    'Nope': function() {
        return 'No, no, definitively no.';
    },
    'Maybe': function() {
        return 'Hum, maybe.';
    }
};


for(var button_label in buttons) {
    var button_callback = buttons[button_label];

    var button_html = $('<button type="button">' + button_label + '</button>');

    button_html.on('click', function() {
        alert('button : ' + $(this).text() + ', callback : ' + button_callback());
    });

    container.append(button_html);
}

View the code on JS Bin

一切正常,但是,正如您所看到的,当点击所有按钮时:调用相同的回调(最后在buttons对象中定义)。我检查了jQuery的doc,也许这是相关的:

  

但是,如果有多个目标元素,则会在第一个目标元素之后为每个目标创建插入元素的克隆副本。

或者,我需要重构我的代码。我测试了不同的解决方案,但都没有。有人可以帮帮我吗?

1 个答案:

答案 0 :(得分:5)

这是传递给回调的循环中的一个好的“变量”问题,它存在于Stack Overflow上十亿次。所以它根本与jQuery无关。

您需要做的是在每个循环期间创建一个新变量。最简单的方法是使用一个立即执行的匿名函数,并将该值作为参数接收。

(function(button_callback) {
    button_html.on('click', function() {
        alert('button : ' + $(this).text() + ', callback : ' + button_callback());
    });
})(button_callback);

Updated JSBin

为什么这有必要?在JavaScript中没有块范围。只有函数才能创建新范围。因此,在原始代码中var button_callback被提升到范围的顶部(包含循环的函数或全局范围,如果没有)。因此,在每次迭代中,您都有相同的变量。并且此变量绑定到匿名函数的闭包。因此,在循环之后,变量具有最后一个值 - 在所有三个函数中。

相关问题