【发布时间】:2021-01-12 02:05:24
【问题描述】:
对此有点尴尬,但假设我在一个名为 iBlock 的父元素中有这组“子”元素,并且在一个函数中,我正在为每个子元素添加一个“onclick”事件,就像这样...... .
someFunction(iBlock) {
var el, iTotal = iBlock.children.length;
for (var i= 0; i < iTotal; i++) {
el=iBlock.children[i];
el.onclick=function(event){myHandler(this, i)};
}
}
所以给定一个像这样的 onclick 处理程序...
function myHandler(elem, n) {
alert("number is: " + n);
}
有点令人惊讶的是,无论我单击哪个子元素,此示例中的处理程序总是显示小于子元素总数的那个。但我知道,total - 1 是循环结束前变量“i”达到的最高数字,并且处理程序除了事件发生时变量的值之外不会传递任何内容。但是理解这并不能帮助我回答这两个问题......
- 如果我真的希望 onclick 函数中的第二个参数传递值 'i' 实际上是 onclick 处理程序 附上,我可以传递什么来代替原始的“i”变量?
- 由于 'i' 是由函数中的 'var' 关键字声明的 添加了处理程序,为什么它仍然有一个值(在这种情况下 总 - 1),安装功能后返回?如果处理程序显示“未定义”,我就不会那么惊讶了。我意识到 这是一个“变量范围”的问题,但我确信它是相关的。
在第一个问题上,我尝试过传递:i+'x',只是为了将它变成一个字符串,希望它会生成一个唯一的实例。这也不起作用......并且元素“单击”只会触发显示的处理程序以显示“4x”。我还尝试创建第二个变量,作为字符串,然后提取数字部分,并将新变量中的最终“值”传递给 onclick 处理程序,就像这样......
someFunction(iBlock) {
var el, iTotal = iBlock.children.length;
for (var i= 0; i < iTotal; i++) {
el=iBlock.children[i];
var n= i+'x'; // make 'i' into a new longer string variable
var r = /\d+/; // regex, to capturei digits
n = n.match(r); // convert the string to only contain the digits
el.onclick=function(event){myHandler(this, n)};
}
}
没有变化。处理程序仍会在我单击的任何元素上显示 total-1。
我看过关于这个主题的类似帖子,例如Extract a number from a string (JavaScript),但我仍然不明白我的第一个问题的补救措施。
PS(我没有尝试使用 'let' 而不是 'var' 创建变量,因为我非常致力于支持某些较旧的浏览器)。 编辑:如果可能的话,我想在那些“旧浏览器”中包含 IE-8。我意识到我不能总是这样做,但在这种情况下我愿意。
编辑:我发现了一个有趣的解决方法,即在我添加处理程序的循环中向每个元素添加我自己的变量,就像这样......
someFunction(iBlock) {
var el, iTotal = iBlock.children.length;
for (var i= 0; i < iTotal; i++) {
el=iBlock.children[i];
el.onclick=function(event){myHandler(this, i)};
el.myIndex=i;
}
}
当然,在我的处理程序中,无论如何我都在传递“this”,我可以通过检查“this.myIndex”来正确恢复“i”的期望值。我听说这很危险,因为它可能会与未来的 DOM 属性发生冲突。
但这似乎是“杂牌”,所以我仍然对答案感兴趣!
【问题讨论】:
-
n 未重新声明,并且您的事件处理程序基本上指向相同的 n 变量,因此它将获得在 r 执行时分配的最后一个值。试试这个:
el.onclick=(function(localn){return function(event){myHandler(this, localn)};})(n); -
在我看来,您需要使用闭包来捕获该变量。你试过吗?
-
在函数中,你声明了一个名为
el的变量,你没有给它分配任何值,但是你使用el.onclick=....你不应该将每个iBlock子分配给el变量第一? -
el 也未定义
-
el = iBlock.children[i]或什么?
标签: javascript scope pass-by-reference pass-by-value