我在 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 函数,或者可能有其他方法来执行此操作。
希望你能帮助我! 先感谢您, 真挚地, 瓦伦丁
问题在于 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>
您需要向按钮添加 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);
}
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);
}
您总是会得到 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);
}
这里有一个更好的解决方案,关于如何在给定数组的情况下创建一系列元素并将它们插入到 DOM 中
EL_dataItem
) 并分配必要的属性和事件处理程序Array.prototype.reduce()
将 data
数组减少为 DocumentFragment 集合。
DocumentFragment API
及其.append()
方法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>
这背后的原因是,当用户单击按钮时,变量
i
的值会发生变化,因为您直接在 onlick
事件处理程序中引用变量。
root.onclick = function() {
console.log(i);
}
您可以替换
onlick
处理程序并通过闭包和 IIFE 解决此问题。
此代码将 i
的值绑定到循环运行时的值,方法是将其作为参数传递并返回一个函数作为处理程序。
root.onclick = (function (i) {
return function () {
console.log(i);
};
})(i);