0

我正在尝试做的是基于通过 AJAX 获得的数据,我正在将页面上的某些元素更改为不同的。一个简化的版本是这样的:

例子:

HTML:

<ul id="friends">
    <li id="1-1" onclick="dont_alert()"> Andy </li>
    <li id="1-2" onclick="dont_alert()"> Paul </li>
    <li id="1-3" onclick="dont_alert()"> Saul </li>
    <li id="1-4" onclick="dont_alert()"> Rita </li>
    <li id="1-5" onclick="dont_alert()"> Greg </li>
</ul>

<input type="button" onclick='callback()' value="Go!" />

相关 JS:函数 alert_this(value) { alert(value); }

function dont_alert() {
    alert('...');
}

function callback() {
    var data_received = [["1","1","Andy"], ["1","5","Greg"]];
    for (friend in data_received) {
        if (data_received[friend][0] == undefined) continue;

        var friend_id = '#'+ data_received[friend][0] +'-'+ data_received[friend][1];
        $(friend_id).attr('onclick', '');
        $(friend_id).css('background', 'red');
        $(friend_id).click(function () { 
            alert_this(data_received[friend][2]);
        });
    }    
}

这样做的结果是两个元素都 alert 'Greg' 而不是适当的值。

任何对答案的刺激将不胜感激!:D

4

2 回答 2

4

您需要创建一个闭包,否则,.click()处理程序将始终提醒循环中最后分配的值friend,因为它们所拥有的只是对该变量的引用。

function callback() {
    var data_received = [["1","1","Andy"], ["1","5","Greg"]];
    for (var friend in data_received) {
        if (data_received[friend][0] == undefined) continue;

        var friend_id = '#'+ data_received[friend][0] +'-'+ data_received[friend][1];
        console.log(friend_id);
        $(friend_id).attr('onclick', '');
        $(friend_id).css('background', 'red');
        (function() {
            var savedValue = data_received[friend][2];
            $(friend_id).click(function(){
                alert(savedValue);
            });
        })();
    }    
}​

演示

于 2012-08-31T12:10:22.933 回答
0

首先,您不应该在 HTML 中使用内联事件处理程序。相反,使用 jQuery 附加它们。

您的问题在于闭包 -friend具有函数范围,在callback. 事件处理程序在friend变量上创建一个闭包。完成callback后,friend == 1. 然后事件处理程序使用这个值。一个修复方法是用来$.each迭代你的数组,这会在变量的值上创建一个闭包。

HTML

<ul id="friends">
    <li id="1-1"> Andy </li>
    <li id="1-2"> Paul </li>
    <li id="1-3"> Saul </li>
    <li id="1-4"> Rita </li>
    <li id="1-5"> Greg </li>
</ul>

<input type="button" id="go" value="Go!" />

JS

$('#friends').on('click', 'li', function() {
    alert('...');
});

$('#go').on('click', function() {
    var data_received = [["1","1","Andy"], ["1","5","Greg"]];
    $.each(data_received, function(i, friend) {
        if (friend[0] === undefined) return;

        $('#'+ friend[0] +'-'+ friend[1])
            .css('background', 'red');
            .click(function() { 
                alert(friend[2]);
                return false;
            });
    });
});
于 2012-08-31T12:24:25.510 回答