英文:
Can I call different effects from multiple buttons generated using a single createElement? (in Javascript)
问题
I'd like to generate a number of buttons using createElement, but I'm having trouble making the buttons do different things when they're clicked. In this example, I would like one button to make the console read "punch 10", and one to make the console read "kick 20".
var joe = {
age: 20,
moves: [
{name: "punch", power: 10,},
{name: "kick", power: 20,},
]
}
function printBtn() {
for (var i = 0; i < joe.moves.length; i++) {
let btn = document.createElement("button");
var n = document.createTextNode(joe.moves[i].name);
var t = document.createTextNode(joe.moves[i].power);
var nr = joe.moves[i].name
var tr = joe.moves[i].power
var linebreak = document.createElement("br")
btn.appendChild(n);
btn.appendChild(linebreak);
btn.appendChild(t);
document.body.appendChild(btn);
btn.style.width = "125px";
btn.style.height = "50px";
btn.style.fontSize = "12px";
btn.onclick = function readOut() {
console.log(nr + " " + tr)
}
}
}
I tried to use innerHTML to assign each button a function, containing variables which I thought would be different for each of the buttons, to make the console.log method say "punch 10" or "kick 20" depending on which button was clicked. However, as the variables change, the outcome does too, which results in my console.log method always resulting in "kick 20".
英文:
I'd like to generate a number of buttons using createElement, but I'm having trouble making the buttons do different things when they're clicked. In this example, I would like one button to make the console read "punch 10", and one to make the console read "kick 20".
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
var joe = {
age: 20,
moves: [
{name: "punch", power: 10,},
{name: "kick", power: 20,},
]
}
function printBtn() {
for (var i = 0; i < joe.moves.length; i++) {
let btn = document.createElement("button");
var n = document.createTextNode(joe.moves[i].name);
var t = document.createTextNode(joe.moves[i].power);
var nr = joe.moves[i].name
var tr = joe.moves[i].power
var linebreak = document.createElement("br")
btn.appendChild(n);
btn.appendChild(linebreak);
btn.appendChild(t);
document.body.appendChild(btn);
btn.style.width = "125px"
btn.style.height = "50px"
btn.style.fontSize = "12px"
btn.innerHTML.onclick = function readOut() {
console.log(nr + " " + tr)
}
}
}
<!-- language: lang-html -->
<button onclick="printBtn();">Go Joe!</button>
<!-- end snippet -->
I tried to use innerHTML to assign each button a function, containing variables which I thought would be different for each of the buttons, to make the console.log method say "punch 10" or "kick 20" depending on which button was clicked. However, as the variables change, the outcome does too, which results in my console.log method always resulting in "kick 20".
答案1
得分: 1
我会在 HTML 中创建所需的按钮,并将 CSS 中的 "visibility: hidden" 应用于这些按钮,并使用 printBtn 函数来通过 document.getElementById("btn").style.visibility = visible 使这些样式可见。
我会添加注释,但我目前还不能添加注释。
英文:
I would just make the buttons you need in html and give the css "visibility: hidden" on those buttons and use the printBtn function to make those styles visable with document.getElementById("btn").style.visibility = visable.
I would comment this but I can't yet.
答案2
得分: 0
这段代码完全实现了你的要求:
const joe = {
age: 20,
moves: [
{name: "punch", power: 10,},
{name: "kick", power: 20,},
]
}
function printBtn() {
for (let i = 0; i < joe.moves.length; i++) {
(function(i) {
const btn = document.createElement("button");
const n = document.createTextNode(joe.moves[i].name);
const t = document.createTextNode(joe.moves[i].power);
const nr = joe.moves[i].name
const tr = joe.moves[i].power
const linebreak = document.createElement("br")
btn.appendChild(n);
btn.appendChild(linebreak);
btn.appendChild(t);
document.body.appendChild(btn);
btn.style.width = "125px";
btn.style.height = "50px";
btn.style.fontSize = "12px";
btn.onclick = () => {
console.log(nr + " " + tr);
}
})(i);
}
}
不过你需要注意2个重要的事情:
1) 首先,btn.innerHTML.onclick
是错误的。你应该在 DOM 元素上调用 onclick
方法(比如 btn
),而不是在 btn.innerHTML
上调用。
2) 其次,你可能会疑惑这是什么:
(function(i) {
// ...
})(i)
由于我们在一个循环内分配了多个事件监听器(点击事件),你必须创建一个临时作用域来保留变量的值(尤其是 nr
和 tr
)。你现在可以将它保留,不要触碰它,因为这是 JavaScript 的难点之一。
祝一切顺利!
英文:
This code achieves exactly what you requested:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const joe = {
age: 20,
moves: [
{name: "punch", power: 10,},
{name: "kick", power: 20,},
]
}
function printBtn() {
for (let i = 0; i < joe.moves.length; i++) {
(function(i) {
const btn = document.createElement("button");
const n = document.createTextNode(joe.moves[i].name);
const t = document.createTextNode(joe.moves[i].power);
const nr = joe.moves[i].name
const tr = joe.moves[i].power
const linebreak = document.createElement("br")
btn.appendChild(n);
btn.appendChild(linebreak);
btn.appendChild(t);
document.body.appendChild(btn);
btn.style.width = "125px";
btn.style.height = "50px";
btn.style.fontSize = "12px";
btn.onclick = () => {
console.log(nr + " " + tr);
}
})(i);
}
}
<!-- language: lang-html -->
<button onclick="printBtn();">Go Joe!</button>
<!-- end snippet -->
However you need to note 2 important things:
1) First btn.innerHTML.onclick
is wrong. You call the method onclick on a DOM Element (like btn
) and not on btn.innerHTML
2) Second, you might have wonder what is this:
(function(i) {
// ...
})(i)
Since we're assigning multiple event listeners (click) inside a for-loop, you'll have to create a temporary scope to preserve the value of the variables (especially nr
and tr
).You can leave it for now and don't touch it since this is one of the difficult aspects of JS.
Regards
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论