我正在使用HTML,JS和CSS开发一个Clicker游戏,但是当我进行for循环并设置onclick时,onclick函数仅适用于最后一个对象。我正在使用JSON数据。
JS:
const Shop = document.getElementById("Shop")
const Upgrades = JSON.parse(json_upgrades)
let IncreasePerClick = function(Amount, ID) {
console.log("Debug!", ID)
let CurrentPerClick = Number(localStorage.getItem("PerClick") || 1)
let CurrentBalance = Number(localStorage.getItem("Cheese") || 0)
let Default = Number(document.getElementById(`Buy${ID}`).getAttribute("default"))
let CostUp = Number(localStorage.getItem(`Buy${ID}CostUp`))
let Cost = Number(localStorage.getItem(`Buy${ID}Cost`) || Default)
console.log(Cost)
if(CurrentBalance >= Cost){
CurrentBalance -= Cost
CurrentPerClick += Amount
Cost += CostUp
localStorage.setItem(`Buy${ID}CostUp`, CostUp)
localStorage.setItem("Cheese", CurrentBalance)
localStorage.setItem("PerClick", CurrentPerClick)
localStorage.setItem(`Buy${ID}Cost`, Cost)
}
}
for(let i = 0; i < Upgrades.length; i+=1){
Shop.innerHTML += `<div class="UpgradeHolder">
<span class="UpgradeName">${Upgrades[i]["name"]}</span>
<button class="UpgradeButton" id="Buy${i}" amountup="${Upgrades[i]["amount"]}" default="${Upgrades[i]["default"]}" costup="${Upgrades[i]["costup"]}" itemtype="${Upgrades[i]["type"]}">Buy for ${Upgrades[i]["default"]}</button>
</div>
`
console.log("Added div!")
let NewUpgradeButton = document.getElementById(`Buy${i}`)
let UpgradeType = NewUpgradeButton.getAttribute("itemtype")
let CostUp = Number(NewUpgradeButton.getAttribute("costup"))
let Default = Number(NewUpgradeButton.getAttribute("Default"))
let AmountUp = Number(NewUpgradeButton.getAttribute("amountup"))
if(UpgradeType == "ClickUpgrade"){
NewUpgradeButton.onclick = function(){
IncreasePerClick(AmountUp, i)
UpdateBalance()
}
console.log("Set Onclick!", i, AmountUp)
}
}
JSON(在js文件中):
const json_upgrades = `[
{"name": "Clickbot", "default": 50, "type": "ClickUpgrade", "amount": 1, "costup": 10},
{"name": "Click Machine", "default": 125, "type": "ClickUpgrade", "amount": 3, "costup": 15}
]`
当我单击除最后一个按钮以外的任何按钮时,它什么也没做,该如何解决?我可以提供屏幕截图。
Screenshot在此屏幕快照中显示了2个按钮,控制台右侧显示“ Debug!1”,其中1是第二个按钮的ID。就是说,按下第二个按钮。
当我按下第一个按钮时,它什么也没做。
编辑:我尝试了几种不同的方法后就可以使用它!
答案 0 :(得分:0)
这是代码进行更改的完整示例,我将在下面评论:https://jsbin.com/hezubuhali/edit?html,js,console,output(要查看其工作原理,您需要单击窗口右侧的“使用JS运行”按钮,在最后一个面板中。)
分配给innerHTML会导致事件侦听器丢失。您需要使用DOM functions。您可以找到其他示例here。
在onclick事件中,您也不应在i
处使用IncreasePerClick(AmountUp, i)
。使代码正常工作时,i
的值将是所有按钮的最后一个值。我在下面提出了一个快速解决方案,供您查看它的工作原理。
总结:
innerHTML
替换为appendChild
。我正在使用模板元素将您的代码转换为DOM元素(您可以看到完整的说明here)this
而不是i
来获取按钮ID。答案 1 :(得分:0)
+=
内部HTML时,由于内部HTML被重写,因此当前应用的事件将被擦除。有几种方法可以解决此问题。以下是将事件应用于Shop
的事件,该事件没有被重写,因此事件保持不变。
例如,另一种方法是运行两次循环,并在编写innerHTML之后应用所有事件。
const Shop = document.getElementById("Shop")
const json_upgrades = '[{"name": "Clickbot", "default": 50, "type": "ClickUpgrade", "amount": 1, "costup": 10},{"name": "Click Machine", "default": 125, "type": "ClickUpgrade", "amount": 3, "costup": 15}]';
const Upgrades = JSON.parse(json_upgrades)
let IncreasePerClick = function(Amount, ID) {
console.log(`click ${ID}`);
}
for(let i = 0; i < Upgrades.length; i+=1) {
Shop.innerHTML += `<div class="UpgradeHolder">
<span class="UpgradeName">${Upgrades[i]["name"]}</span>
<button class="UpgradeButton" id="Buy${i}" amountup="${Upgrades[i]["amount"]}" default="${Upgrades[i]["default"]}" costup="${Upgrades[i]["costup"]}" itemtype="${Upgrades[i]["type"]}">Buy for ${Upgrades[i]["default"]}</button>
</div>`;
let NewUpgradeButton = document.getElementById(`Buy${i}`);
let UpgradeType = NewUpgradeButton.getAttribute("itemtype");
let CostUp = Number(NewUpgradeButton.getAttribute("costup"));
let Default = Number(NewUpgradeButton.getAttribute("Default"));
let AmountUp = Number(NewUpgradeButton.getAttribute("amountup"));
if(UpgradeType == "ClickUpgrade") {
Shop.addEventListener('click', function(e, t) {
if(e.toElement.id != NewUpgradeButton.id) return;
IncreasePerClick(AmountUp, i);
// UpdateBalance();
});
}
}
<div id="Shop"></div>