我正在迭代容器中的元素并将onClick添加到每个元素。我希望在单击元素时执行一个接受id作为参数的方法。 id对每个元素都是唯一的。
以下是我的代码:
$(document).ready(function()
{
var conElement = document.getElementById("my-container");
if (conElement)
{
var bookElements = conElement.getElementsByClassName("book-elements");
for (var element = bookElements.length; element--; )
{
var bookElement = bookElements[element];
var bookId = bookElement.getAttribute('book-id');
alert ('Book id is ' + bookId);
bookElement.onclick = function() {showBookSummary(bookId)};
}
}
});
function showBookSummary(bookId)
{
alert ('Book id inside showBookSummary is ' + bookId);
}
问题:每次点击任何元素时都会传递相同的图书ID。假设我有3个元素,第1个元素的id是“123”,第2个元素是“456”,第3个元素是“789”。每当我点击3个元素中的任何一个时,它总是将id“123”作为bookId传递给showBookSummary函数。
我在这里遗漏了什么吗?
答案 0 :(得分:0)
<强>问题强>
您的问题是由于bookId
是保留其值的常规JS变量引起的。 bookId不是保存该书的bookId
,而是在运行代码后的内容。
代码执行如下:
bookId = 789 (id of first book because you are starting at top and decrementing)
bookId = 456 (second element)
bookId = 123 (third element)
然后bookId
仍然是123,因为您仍在使用bookId
变量。因此,您随时致电:
showBookSummary(bookId);
bookId
仍 123。
<强>解强>
相反,我认为你应该改变这一行:
bookElement.onclick = function() {showBookSummary(bookId)};
为:
bookElement.onclick = (function(t){return function(){showBookSummary(t);};})(bookId);
编辑:从评论中点击@RobG处理程序。是的,我现在意识到将它作为字符串放置是行不通的。通过将bookId
替换为t
并基本上存储正确的bookId
而不是使用在执行期间更改的变量,这可以做类似的事情。
编辑:可能更容易解决方案:
根据其他SO答案(标记为重复),似乎相对较新的let
关键字也可以在此上下文中提供帮助。它创建了循环范围的本地变量,而不是函数。因此,如果您只是更改bookId
的声明:
var bookId = ...
到let
:
let bookId = ...
这也应该有用。我还没有尝试过,但看起来很有希望。
另外,如果您使用的是jQuery,则可以替换可怕的:
document.getElementById("id")
document.getElementsByClassName("class")
for(var element = bookElements.length; element--; )
getAttribute("attr")
element.onclick = function()
使用jQuery的内置缩写:
$("#id")
$(".class")
elements.each(
attr("attr")
elements.click(function()