我在一个循环中分配事件侦听器。我将一个变量传递给事件侦听器函数,该变量在整个循环中都会发生变化。然而,我有一个问题。所有的事件侦听器都在接收循环中变量的最后一个值,而不是我打算在循环中的每个点发送的值。分配事件侦听器的函数如下所示
let arr;
let newElem;
let id;
for (let i = 6; i < 13; i++) {
arr = this.state.cards[i];
if (arr.length > 1) {
for (let j = 0; j < arr.length; j++) {
if (j !== arr.length-1) {
newElem = document.createElement('div');
newElem.id = 'p' + i + '-' + (j+1);
document.getElementById('p' + i + '-' +
j).appendChild(newElem);
} else {
id = 'p' + i + '-' + j;
document.getElementById(id).className = 'cardLocations
faceUp';
newElem = document.createElement('p');
newElem.innerHTML = arr[j].id;
document.getElementById(id).appendChild(newElem);
document.getElementById(id).addEventListener('click', () =>
{this.selectCardsFromBoard(id)});
}
}
} else {
newElem = document.createElement('p');
newElem.innerHTML = arr[0].id;
document.getElementById('p6-0').appendChild(newElem);
document.getElementById('p6-0').addEventListener('click', () =>
{this.selectCardsFromBoard('p6-0')});
}问题是,每当我单击分配了事件侦听器的任何div时,都会使用相同的值调用函数selectCardsFromBoard,这是'id‘在循环中达到的最后一个值。我希望在赋值时能够使用'id‘的值调用函数。我认为这是某种通过引用传递的问题,但我无法弄清楚。
发布于 2017-05-24 09:12:58
您希望在for循环的上下文中声明id变量。目前,您正在将id声明为一个全局变量,当您的事件被调用时,循环已经运行完了。你需要做的就是去掉let id;' at the top of the program and changeid = 'p‘+i+ '-’+ j;tolet id = 'p‘+i+ '-’+ j;`
发布于 2017-05-24 09:17:47
这是因为所有事件处理程序共享相同的id变量。您可以在循环内定义它,以便在每次迭代中限定它的范围,也可以将事件处理程序更改为
document.getElementById(id).addEventListener(
'click',
event => this.selectCardsFromBoard(event.currentTarget.id)
);有关该问题的更多一般信息,请参阅JavaScript closure inside loops – simple practical example
我可能会完全删除id变量并这样做
// outside the loops
const clickHandler = event => this.selectCardsFromBoard(event.currentTarget.id)
// ...
const element = document.getElementById('p' + i + '-' + j);
element.className = 'cardLocations faceUp';
element.addEventListener('click', clickHandler);
// why is this variable defined outside of your loop?
const newElem = document.createElement('p');
newElem.innerHTML = arr[j].id;
element.appendChild(newElem);没有必要使用相同的参数重复调用getElementById。可能还有其他东西可以改进(例如,你可以利用事件委托,而不是将相同的处理程序分配给这么多对象),这只关注于id变量。
https://stackoverflow.com/questions/44147320
复制相似问题