我刚刚try 了JavaScript,并try 了这段代码.

var elements = document.getElementsByTagName("p");
var n = elements.length; // Should be: 10

for (var i = 0; i < n; i++) {
  elements[i].onclick = function () {
    console.log("This is element #" + i);
  };
}
<p>Element: #1</p>
<p>Element: #2</p>
<p>Element: #3</p>
<p>Element: #4</p>
<p>Element: #5</p>

然而,当代码运行时,一些奇怪的事情发生了.基本上,例如,如果你点击元素#1,它会说你点击了元素#5.


这就是我想知道的:

  1. 为什么会这样?
  2. 有解决办法吗?

推荐答案

您可以使用下面的代码来纠正这些问题.

var elements = document.getElementsByTagName("p");
var n = elements.length;

function makeHandler(num) {
     return function() {
         console.log("This is element #" + num);
     };
};

for (var i = 0; i < n; i++) {
    elements[i].onclick = makeHandler(i + 1);
}

让我们解释一下代码.


基本上,在这段代码中,每次我们通过循环时,都会立即执行makeHandler,每次我们接收到当时的值i + 1,并将其绑定到一个范围为num的变量.

外部函数(makeHandler)返回内部函数(匿名函数)(它也使用这个范围为num的变量),元素的onclick被设置为该内部函数.

这确保每个onclick接收并使用正确的i值(通过作用域num变量).

Javascript相关问答推荐

使用GraphQL查询Uniswap的ETH价格

将核心模块导入另一个组件模块时存在多个主题

连接到游戏的玩家不会在浏览器在线游戏中呈现

使用NextJS+MongoDB+Prisma ORM获取无效请求正文,无法发布错误

如何在JAVASCRIPT中合并两组对象并返回一些键

如何利用CSS中的隐藏元素实现平滑扩展和防止网格行间隙

在不扭曲纹理的情况下在顶点着色器中旋转UV

在查看网页时,如何使HTML中的按钮工作方式类似于鼠标上的滚轮或箭头键?

将相关数据组合到两个不同的数组中

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

不协调嵌入图片

用Reaction-RT-Chart创建实时条形图

select 2-删除js插入的项目将其保留为选项

如何使用Reaction路由导航测试挂钩?

在将元素追加到DOM之前,createElement()是否会触发回流?混淆abt DocumentFragment行为

ReactJS Sweep Line:优化SciChartJS性能,重用wasmContext进行多图表渲染

已在EventListener中更新/更改异步的React.js状态对象,但不会导致组件重新呈现

Electron -如何指向ASAR生成的应用程序之外的路径

将文本复制到循环结果

有没有办法让动画在中止时结束?