简体   繁体   English

使用 for 循环设置 onclick 功能

[英]Setting onclick function with for loop

I'm working on a clicker game in HTML, JS and CSS but when I go to do a for loop and set onclick, the onclick function only works for the last object.我正在使用 HTML、JS 和 CSS 开发点击游戏,但是当我执行 for 循环并设置 onclick 时,onclick 函数仅适用于最后一个对象。 I'm using JSON data.我正在使用 JSON 数据。

JS: 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 (in js file): 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}
]`

When I click on any button other than the last one it doesn't do anything, how can I fix this?当我点击除最后一个按钮之外的任何按钮时,它什么也没做,我该如何解决这个问题? I can provide screenshots.我可以提供截图。

Screenshot in this screenshot it shows the 2 buttons, on the right the console says "Debug! 1", 1 being the ID of the 2nd button.此屏幕截图中的屏幕截图显示了 2 个按钮,控制台右侧显示“调试!1”,1 是第二个按钮的 ID。 That is said as a result of pressing the 2nd button.这是按第二个按钮的结果。

When I press the first button, it does nothing.当我按下第一个按钮时,它什么也不做。

Edit: I got it to work after trying a few different things!编辑:我尝试了一些不同的东西后让它工作了!

Can you provide a screenshot could not get your point. 您能否提供一个无法理解的截图。 Actually it looks OK 其实看起来还可以

Here is a full example of your code working with the changes I will comment below: https://jsbin.com/hezubuhali/edit?html,js,console,output (to see it working you need to click in the button "Run with JS" on the right side of your window, in the last panel).这是我将在下面评论的更改代码的完整示例: https : //jsbin.com/hezubuhali/edit?html,js,console,output (要查看它是否正常工作,您需要单击“运行”按钮JS”在窗口的右侧,在最后一个面板中)。

Assignments to innerHTML causes the loss of the event listeners.分配给innerHTML 会导致事件侦听器丢失。 You need to use DOM functions .您需要使用DOM 函数 You can find additional examples here .您可以在此处找到其他示例。

You also should not use i at IncreasePerClick(AmountUp, i) in your onclick event.你也不应该在你的 onclick 事件中使用i at IncreasePerClick(AmountUp, i) The value of i will be the last value for all the buttons when you make your code works.当您使代码有效时, i的值将是所有按钮的最后一个值。 I proposed a quick solution below for you to see it working.我在下面提出了一个快速解决方案供您查看它的工作原理。

In summary:总之:

  • I replaced innerHTML with appendChild .我用appendChild替换了innerHTML I am using a template element to convert your code to DOM elements (you can see a full explanation here )我正在使用模板元素将您的代码转换为 DOM 元素(您可以在此处查看完整说明)
  • I am using this instead of i inside the onclick event to get your button ID.我在 onclick 事件中使用this而不是i来获取您的按钮 ID。

When you += the innerHTML the current applied events get erased, because the innerHTML gets rewritten.当您+= innerHTML 时,当前应用的事件会被删除,因为innerHTML 会被重写。 There are several ways to get around this.有几种方法可以解决这个问题。 The one below is applying the events to Shop , which is not getting rewritten, so the event stays.下面的一个是将事件应用于Shop ,它没有被重写,所以事件保持不变。 Another way for example would be to run the loop twice and apply all the events after the innerHTML has been written.例如,另一种方法是运行两次循环并在编写 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM