2
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)。

4

2 回答 2

8

问题是在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));
});
于 2013-05-15T12:56:58.967 回答
2

您得到错误数字的原因是您正在创建的事件处理函数获得对变量的持久引用,而不是创建它们时的副本。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);
        });
    }
});

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

使用构建器函数

(非 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);
    };
}

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

forEach

(非 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);
        });
    }
});

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

于 2013-05-15T12:59:23.027 回答