一年前在大学类(class)中学习了一些基础知识后,我刚刚开始自学 Javascript。对于我要编写的网络应用程序,我需要允许用户“选择”表格的行,最好是通过单击它们。我有很强的 Python 背景,我的方法可能带有 GTK 范式的味道。我有一种挥之不去的恐惧,当有一种更标准或被接受的方式时,我试图以某种方式“重新发明轮子”,但就像我说的,还不太了解 Javascript。我尝试执行此操作的 Javascript 代码是:
//Get list of rows in the table
var table = document.getElementById("toppings");
var rows = table.getElementsByTagName("tr");
var selectedRow;
//Row callback; reset the previously selected row and select the new one
function SelectRow(row) {
if (selectedRow !== undefined) {
selectedRow.style.background = "#d8da3d";
}
selectedRow = row;
selectedRow.style.background = "white";
}
//Attach this callback to all rows
for (var i = 0; i < rows.length; i++) {
var idx = i;
rows[idx].addEventListener("click", function(){SelectRow(rows[idx])});
}
这显然不起作用,因为循环退出后 idx 等于 rows.length - 1,因此 SelectRow 中的行参数是 rows[rows.length - 1],它始终是最后一行;也就是说,i 的值不会作为参数“保存”到事件监听器回调中。如何使用事件监听器自己保存的参数来调用事件监听器? This thread似乎提供了一种使用 onclick 属性来执行此操作的方法,但我知道这已被弃用,并且 addEventListener (或某些与 IE 兼容的可怕的 addEvent 库)现在是执行此操作的“正确”方法。
最佳答案
您遇到关闭问题。这是一个引用:JavaScript closure inside loops – simple practical example
试试这个:
for (var i = 0; i < rows.length; i++) {
(function (idx) {
rows[idx].addEventListener("click", function() {
SelectRow(rows[idx]);
});
})(i);
}
当然,您实际上并不需要将 rows[idx]
传递给 SelectRow
- 您可以传递 this
而不必处理创建一个闭包来捕获当时的 i 值。所以像这样:
for (var i = 0; i < rows.length; i++) {
rows[idx].addEventListener("click", function() {
SelectRow(this);
});
}
在示例中,我包含了一个用于将事件有效附加到元素的函数:
function addEvent(element, evt, callback) {
if (element.addEventListener) {
element.addEventListener(evt, callback, false);
} else if (element.attachEvent) {
element.attachEvent("on" + evt, callback);
} else {
element["on" + evt] = callback;
}
}
尝试使用现代标准addEventListener
,然后尝试使用IE的方式 - attachEvent
,然后尝试使用DOM0方式 - element.onevent
。有几个地方可以从几个地方获得这个功能,甚至可能有更好的版本,但这现在应该可以工作:)
关于Javascript:向表的 "select"行添加功能,使用参数调用事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15572082/