通过 for 循环绑定的事件中的数字值错误

Number value wrong in event bound through a for loop

本文关键字:数字 错误 事件 循环 绑定 通过 for      更新时间:2023-09-26
var rows = document.getElementsByClassName('row');
for (var i = 0, l = rows.length; i < l; i++) {
    if (i % 2 === 0) {
        $(rows[i]).click(function () {
            alert('I am line number ' + i);
        }
    }
}

你好如何获取每行的实际行号?因为我在偶数行上触发单击事件时得到的所有内容,因此会提醒上限值(即:rows.length = 7,i每单击一行为 6(。

问题是在

触发click事件时,循环迭代已经更改了i变量。从理论上讲,您可以使用闭包来使事情正常工作,即

for (var i = 0, l = rows.length; i < l; i++) {
    if (i % 2 === 0) {
        (function(i) {
            $(rows[i]).click(function() {
                alert("I am line number " + i);
            });
        )(i);
    }
}

实际上,如果你使用jQuery(正如我从代码中理解的那样(,使用:even选择器会更容易:

$(".row:even").click(function() {
    alert("I am line number " + $(".row").index(this));
});

您得到错误数字的原因是,您正在创建的事件处理程序函数获得了对i变量的持久引用而不是创建时的副本。

解决它的方法是让处理程序关闭不会改变的东西。这里有三种方法可以做到这一点,第一种是特定于jQuery的(看起来你正在使用jQuery(:

jQuery的each

看起来你正在使用jQuery,在这种情况下,你可以使用它的each来获取一个不会改变的索引:

var rows = $(".row");
rows.each(function(index) {
    if (index % 2 === 0) {
        $(this).click(function() {
            alert('I am line number ' + index);
        });
    }
});

现在,事件处理程序函数关闭了调用我们each函数的index参数,并且由于该index参数永远不会更改,因此您会在警报中看到正确的数字。

使用生成器函数

(Non-jQuery(你可以用一个构建器函数来解决这个问题:

var rows = document.getElementsByClassName('row');
for (var i = 0, l = rows.length; i < l; i++) {
    if (i % 2 === 0) {
        $(rows[i]).click(buildHandler(i));
    }
}
function buildHandler(index) {
    return function () {
        alert('I am line number ' + index);
    };
}

在这里,事件处理程序函数在 buildHandler 中的 index 参数上关闭,并且由于该index参数永远不会更改,因此您会在警报中看到正确的数字。

forEach

(Non-jQuery(你也可以使用 ES5 的 forEach 函数(这是 ES5 之前的环境中可以填充的 ES5 功能之一(来解决这个问题:

var rows = document.getElementsByClassName('row');
Array.prototype.forEach.call(rows, function(row, index) {
    if (index % 2 === 0) {
        $(row).click(function () {
            alert('I am line number ' + index);
        });
    }
});

这与上述两个的工作方式相同,通过关闭index,这不会改变。