Javascript 事件。在循环和变量中观察

Javascript 事件。在循环和变量中观察,javascript,event-handling,prototypejs,Javascript,Event Handling,Prototypejs,为了把事情放在上下文中,我通过Ajax加载了一个项目列表,创建了一个div,其中包含每个项目的主要信息,并希望在单击页面时在页面上显示详细信息。因此,我在onSuccess中有这样的代码: items = transport.responseText.evalJSON(); // my list of objects that contains all the details I'll need for that page for (var itemID in items) { newD

为了把事情放在上下文中,我通过Ajax加载了一个项目列表,创建了一个div,其中包含每个项目的主要信息,并希望在单击页面时在页面上显示详细信息。因此,我在onSuccess中有这样的代码:

items = transport.responseText.evalJSON(); // my list of objects that contains all the details I'll need for that page
for (var itemID in items)
{
    newDiv = ... // Creating my div with main infos
    $('myDiv').appendChild(newDiv);

    // More code to make everything look pretty and that works fine

    Event.observe(newDiv, 'click', function() { loadItem(itemID); });
}
loadItem是我的函数,它将显示所有项目的详细信息。我的问题是,在创建observe事件时,itemID不会被它的值替换,因此它总是为所有项返回相同的ID


你知道我该怎么解决吗?我检查了prototype doc上的bind,它似乎是为这些情况制作的,但可能没有得到它,因为它对我不起作用。

要获得最小影响修复,请替换您的
事件。用以下内容观察
行:

Event.observe(newDiv, 'click', loadItem.curry(itemID));
说明:

在原始代码中,您正在创建的事件处理程序函数将关闭(持久引用)
itemID
变量,因此将在调用事件处理程序时使用该变量的值,而不是在将其分配给事件时使用该变量的值。对于所有处理程序函数,该值将是
itemID
在循环中的最后一个值

使用修改后的代码,我们使用Prototype的函数,它将为您创建一个函数,当调用该函数时,它将使用您提供的参数调用底层函数
curry
。(名字叫哈斯凯尔·库里(Haskell Curry)提出了这项技术,尽管有人认为他不是第一个提出这项技术的人。)我们自己也可以这样做:

items = transport.responseText.evalJSON(); // my list of objects that contains all the details I'll need for that page
for (var itemID in items)
{
    newDiv = ... // Creating my div with main infos
    $('myDiv').appendChild(newDiv);

    // More code to make everything look pretty and that works fine

    Event.observe(newDiv, 'click', prepLoadItem(itemID));
}

function prepLoadItem(id) {
    return function() {
        loadItem(id);
    };
}
…但由于原型具有通用功能,我们不必这样做

主题外:项目是数组吗?如果不是,请忽略此离题注释。如果是这样,请不要在
中使用
for..in来循环,或者至少,除非您采取了一些预防措施,否则上述代码无法正确执行,但是,..in
中的
不用于循环遍历数组的索引;它用于循环遍历对象的属性。数组对象很可能具有数组索引以外的属性(事实上,如果您使用的是Prototype,它们确实具有)