为循环函数中的元素指定单击

Assigning a click to elements in a looping function

本文关键字:单击 元素 循环 函数      更新时间:2023-09-26

我正在导入#parentEle的子级,对每个子级进行复制,并使用新的ID-#eleCopy(i) 将复制的对象推送到数组中

我还试图为导入的原始对象分配一个单击功能。单击它将更改其副本(从数组中引用)的CSS。但受影响的副本始终是最后一个加载的副本。我希望通过数组中的索引号来引用它。。。如何在单击函数中"冻结"正确的数组引用,使$(this) 0对应于ar[0],$(this)`1对应于ar[1],依此类推?

var ar = [];
var i = 0;
$('#parentEle').children().each(function() {
        ... // copy of $(this) is created: $('#eleCopy'+i)
        ar.push($('#eleCopy'+i));

        $(this).on('click', function() {
            ar[i].css({ ... });
        });
        i++;
});

请参阅以下问题以了解问题的解释:

  • 在for循环中分配单击处理程序
  • 循环中的JavaScript闭包——一个简单的实际示例

在您的情况下,解决方案非常简单:由于您已经在使用.each,因此不需要保留外部计数器。当前索引作为参数传递给回调:

// method signature: each( function(index, Element) )
$('#parentEle').children().each(function(i) {
    ... // copy of $(this) is created: $('#eleCopy'+i)
    ar.push($('#eleCopy'+i));
    $(this).on('click', function() {
        ar[i].css({ ... });
    });
});

但是,问题是您是否需要通过阵列引用克隆。要访问事件处理程序中的克隆,可以直接引用它:

$('#parentEle').children().each(function(i) {
    var $copy = ...; // copy of $(this) is created: $('#eleCopy'+i)
    $(this).on('click', function() {
        $copy.css({ ... });
    });
});

这是因为绑定的事件处理程序是闭包

这两种解决方案的缺点是,在每次迭代中都要创建一个新的事件处理程序,即使它们都做相同的事情。您可以利用jQuery的.data API存储对原始节点的克隆的引用,并将单个事件处理程序绑定到元素:

$('#parentEle').children().each(function(i) {
    var $copy = ...; // copy of $(this) is created: $('#eleCopy'+i)
    $(this).data('copy', $copy);
}).on('click', function() {
    $(this).data('copy').css({ ... });
});

这是一个范围问题。

当点击事件发生并执行ar[i].css({ ... })时,所有对的调用都已经增加了i的值

i++;

所以i等于#parentEle 的子代数

为了获得所需的行为,请将代码包装在闭包中:

更换

$(this).on('click', function() {
    ar[i].css({ ... });
});

带有

(function(i) {
    $(this).on('click', function() {
        ar[i].css({ ... });
    });
})(i);

有关javascript闭包的更多信息,请参阅以下答案

为什么不:

$('#parentEle').find('[id^="eleCopy"]').each(function() {
    $(this).css({ ... });
}

每个()

启动