如何定义带有变量的onclick函数? JavaScript

问题描述 投票:0回答:6

我在 Web 开发方面还很陌生,我正在尝试在 JavaScript 函数中创建多个按钮,并在 for 循环中定义它们的 onclick 函数。

我想要什么: 当我点击按钮时,我想恢复与该按钮关联的值。

我有什么: 当我单击任何按钮时,我将恢复与最后一个按钮关联的值。

我做了一个简单的例子来说明我正在尝试做的事情:

HTML:

<html>
  <body>
    <div id="container">
    </div>
    <script src="script.js" charset="utf-8"></script>
  </body>
</html>

JS:

const data = [1, 2, 3, 4, 5];
var i;
for (i = 0;i < data.length;i++) {
  const root = document.createElement('button');
  root.setAttribute("class", "exerciceBox");
  root.textContent = i;
  root.onclick = function() {
    console.log(i);
  }
  document.getElementById("container").append(root);
}

我不知道是否有最好的方法来为 JS 文件中创建的按钮声明 .onclick 函数,或者可能有其他方法来执行此操作。

希望你能帮助我! 先感谢您, 真挚地, 瓦伦丁

javascript buttonclick
6个回答
2
投票

问题在于 var 语句,并且存在范围问题。 var 语句声明函数范围或全局范围的变量。为了解决这个问题,通过

let
语句声明变量 i 以维持 for 循环中的范围。

可能的解决方案如下

const data = [1, 2, 3, 4, 5];
for (let i = 0;i < data.length;i++) {
  const root = document.createElement('button');
  root.setAttribute("class", "exerciceBox");
  root.textContent = i;
  root.onclick = function() {
    console.log(i);
  }
  document.getElementById("container").append(root);
}
<html>
  <body>
    <div id="container">
    </div>
    <script src="script.js" charset="utf-8"></script>
  </body>
</html>


1
投票

您需要向按钮添加 value 属性,具体操作方法如下:

const data = [1, 2, 3, 4, 5];
for (i = 0;i < data.length;i++) {
  const root = document.createElement('button');
  root.setAttribute("class", "exerciceBox");
  // set the value of your button to i
  root.setAttribute("value", i);
  root.textContent = i;
  root.onclick = function() {
  // get the value using 'this' 
  console.log(this.value);
  }
  document.getElementById("container").append(root);
}

0
投票

js中索引从0开始。

const data = [1, 2, 3, 4, 5];

for (let i = 0; i < data.length; i++) {
  const root = document.createElement('button');
  root.setAttribute("class", "exerciceBox");
  root.textContent = i;
  root.onclick = function() {
    console.log(i++); // this prints out i (index) + 1
  }
  document.getElementById("container").append(root);
}

0
投票

您总是会得到 i 的最后一个值,因为 for 会递增它直到循环结束,然后,当您单击按钮时,您会看到递增的值。 试试这个:

for (let i = 0; i < data.length; i++) {
    const root = document.createElement('button');
    root.setAttribute("class", "exerciceBox");
    root.textContent = i;
    let thisButtonI = i; //Make a copy of the actual value of i
    root.onclick = function() {
        console.log(thisButtonI); //use the copy, not the original i
    }
    document.getElementById("container").append(root);
}

0
投票
  • 不要在循环内创建函数。它很容易出现错误,因为一旦循环退出,该函数可能会被覆盖并附加最后一个循环值退出。
  • 不要修改循环内的 DOM - 这会导致混乱、不必要的重新布局和重绘

这里有一个更好的解决方案,关于如何在给定数组的情况下创建一系列元素并将它们插入到 DOM 中

  • 创建按钮的蓝图 (
    EL_dataItem
    ) 并分配必要的属性和事件处理程序
  • 使用
    Array.prototype.reduce()
    data 数组
    减少
    DocumentFragment 集合。
  • 使用
    DocumentFragment API
    及其
    .append()
    方法
  • 填充 DocumentFragment 后,使用
    Element.append()
    在需要的地方插入按钮 - 一次性全部插入

// Helpers
const ELNew = (sel, attr) => Object.assign(document.createElement(sel), attr || {});
const EL = (sel, EL) => (EL || document).querySelector(sel);

// Your data Array
const data = [1, 2, 3, 4, 5];

// Button Blueprint
const EL_dataItem = (item) => ELNew("button", {
  type:        "button",
  className:   "exerciceBox", // cice?..
  textContent: item,
  onclick()    { console.log(item); },
});

// Create all buttons (Append into DocumentFragment)
const DF_items = data.reduce((DF, item) => {
  DF.append(EL_dataItem(item));
  return DF;
}, new DocumentFragment());

// Append DocumentFragment once.
EL("#container").append(DF_items);
<div id="container"></div>


0
投票

这背后的原因是,当用户单击按钮时,变量

i
的值会发生变化,因为您直接在
onlick
事件处理程序中引用变量。

root.onclick = function() {
    console.log(i);
}

您可以替换

onlick
处理程序并通过闭包和 IIFE 解决此问题。 此代码将
i
的值绑定到循环运行时的值,方法是将其作为参数传递并返回一个函数作为处理程序。

root.onclick = (function (i) {
    return function () {
      console.log(i);
      }; 
})(i);
© www.soinside.com 2019 - 2024. All rights reserved.