使用for循环设置onclick函数

时间:2019-11-24 20:05:17

标签: javascript html

我正在使用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。就是说,按下第二个按钮。

当我按下第一个按钮时,它什么也没做。

编辑:我尝试了几种不同的方法后就可以使用它!

2 个答案:

答案 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
  • 我在onclick事件中使用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>