Onclick功能更改为所有已更改元素的相同功能

时间:2012-08-31 12:08:19

标签: javascript jquery function onclick

我想要做的是基于通过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:     function alert_this(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]);
        });
    }    
}

结果是两个元素警告'Greg'而不是适当的值。

对此答案的任何刺激将非常感谢! :d

2 个答案:

答案 0 :(得分:4)

您需要创建 闭包 ,否则.click()处理程序将始终提醒最后指定的值{ {1}}在循环中,因为它们只有一个引用到这个变量。

friend

<强> DEMO

答案 1 :(得分: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;
            });
    });
});