使用带有 args 的 onclick 处理程序克隆
clone with onclick handler with args
我正在克隆一个元素,该元素将有一个 onclick 处理程序。该事件处理程序将作为参数发送一个 ID。
我的问题是当我点击元素时,他发送了最后一个 cicle 的 ID。
这是我的 javascript 代码:
function cloneActions(idRoutine){ //clone elements
var actionDiv = document.getElementById("actionsImages-"+idRoutine).getElementsByClassName("actionImage"); //parent with content that must be cloned
var allActions = document.getElementById("actions"); //parent div
while (allActions.firstChild) { //remove all existing imgs
allActions.removeChild(allActions.firstChild);
}
for(var i=0; i < actionDiv.length; i++){ //set all images and handlers
var image = actionDiv[i].cloneNode(true);
var id = image.id;
image.onclick = function() { selectAction(id);};
allActions.appendChild(image);
}
}
function selectAction(id){ //handler function
///jquery
}
和 html 代码:
<div id="actionsImages-«id»" class="tile__list actionsImages">
<img src='sortable/st/foo.jpg' class='actionImage' id=«id» title='foo'/>
</div>
我做错了什么??
这是您在 javascript 中学习 for
循环、变量提升和异步事件的课程。别担心,我们都经历过这一课。这里是:
这是你的 for
循环:
for(var i=0; i < actionDiv.length; i++) {
var image = actionDiv[i].cloneNode(true);
var id = image.id;
image.onclick = function() { selectAction(id);};
allActions.appendChild(image);
}
这与这样做相同:
var image;
var id;
for(var i=0; i < actionDiv.length; i++) {
image = actionDiv[i].cloneNode(true);
id = image.id;
image.onclick = function() { selectAction(id);};
allActions.appendChild(image);
}
这是因为 variables in javascript are hoisted to the the top of their scope 在 运行 时间内。这意味着你的 for
循环 运行s,你的变量 image
和 id
在循环的每次迭代中被设置为一个新值,当循环是完成后,变量将保存循环 .
最后一次迭代的值
(再读一遍粗体部分)
然后,在未来的某个时间,您的用户点击图像,您的点击处理程序调用函数 selectAction
并传递 id
。好吧,如果你再次阅读 粗体 中的文本,你的 id
变量将保存你的 [=15] 的最后一次迭代的 值=]循环.
(再读一遍粗体部分)
为了说明这个问题,让我们把它分解到最简单的部分。将此代码复制到您的控制台:
for (var i = 0; i < 5; i++) {
var someVar = i;
setTimeout(function () {
console.log("The value of 'someVar' is " + someVar);
}, i * 300);
}
看看someVar
怎么每次都等于4。这就是你问题的症结所在。
要解决您的问题,您可以像这样使用 "bind" 函数:
var image, id, i;
for(i=0; i < actionDiv.length; i++) {
image = actionDiv[i].cloneNode(true);
id = image.id;
image.onclick = selectAction.bind(image, id)
allActions.appendChild(image);
}
我会让您了解函数绑定的工作原理 here。
另一个解决方案是在 for
循环中调用一个函数:
function doCoolStuff (i) {
var image = actionDiv[i].cloneNode(true);
var id = image.id;
image.onclick = function () { selectAction(id); };
allActions.appendChild(image);
}
for(var i=0; i < actionDiv.length; i++) {
doCoolStuff(i);
}
我正在克隆一个元素,该元素将有一个 onclick 处理程序。该事件处理程序将作为参数发送一个 ID。 我的问题是当我点击元素时,他发送了最后一个 cicle 的 ID。
这是我的 javascript 代码:
function cloneActions(idRoutine){ //clone elements
var actionDiv = document.getElementById("actionsImages-"+idRoutine).getElementsByClassName("actionImage"); //parent with content that must be cloned
var allActions = document.getElementById("actions"); //parent div
while (allActions.firstChild) { //remove all existing imgs
allActions.removeChild(allActions.firstChild);
}
for(var i=0; i < actionDiv.length; i++){ //set all images and handlers
var image = actionDiv[i].cloneNode(true);
var id = image.id;
image.onclick = function() { selectAction(id);};
allActions.appendChild(image);
}
}
function selectAction(id){ //handler function
///jquery
}
和 html 代码:
<div id="actionsImages-«id»" class="tile__list actionsImages">
<img src='sortable/st/foo.jpg' class='actionImage' id=«id» title='foo'/>
</div>
我做错了什么??
这是您在 javascript 中学习 for
循环、变量提升和异步事件的课程。别担心,我们都经历过这一课。这里是:
这是你的 for
循环:
for(var i=0; i < actionDiv.length; i++) {
var image = actionDiv[i].cloneNode(true);
var id = image.id;
image.onclick = function() { selectAction(id);};
allActions.appendChild(image);
}
这与这样做相同:
var image;
var id;
for(var i=0; i < actionDiv.length; i++) {
image = actionDiv[i].cloneNode(true);
id = image.id;
image.onclick = function() { selectAction(id);};
allActions.appendChild(image);
}
这是因为 variables in javascript are hoisted to the the top of their scope 在 运行 时间内。这意味着你的 for
循环 运行s,你的变量 image
和 id
在循环的每次迭代中被设置为一个新值,当循环是完成后,变量将保存循环 .
(再读一遍粗体部分)
然后,在未来的某个时间,您的用户点击图像,您的点击处理程序调用函数 selectAction
并传递 id
。好吧,如果你再次阅读 粗体 中的文本,你的 id
变量将保存你的 [=15] 的最后一次迭代的 值=]循环.
(再读一遍粗体部分)
为了说明这个问题,让我们把它分解到最简单的部分。将此代码复制到您的控制台:
for (var i = 0; i < 5; i++) {
var someVar = i;
setTimeout(function () {
console.log("The value of 'someVar' is " + someVar);
}, i * 300);
}
看看someVar
怎么每次都等于4。这就是你问题的症结所在。
要解决您的问题,您可以像这样使用 "bind" 函数:
var image, id, i;
for(i=0; i < actionDiv.length; i++) {
image = actionDiv[i].cloneNode(true);
id = image.id;
image.onclick = selectAction.bind(image, id)
allActions.appendChild(image);
}
我会让您了解函数绑定的工作原理 here。
另一个解决方案是在 for
循环中调用一个函数:
function doCoolStuff (i) {
var image = actionDiv[i].cloneNode(true);
var id = image.id;
image.onclick = function () { selectAction(id); };
allActions.appendChild(image);
}
for(var i=0; i < actionDiv.length; i++) {
doCoolStuff(i);
}