0

I just started studying JS and I'm currently simulating something that will apply to my project Basically, I'm trying to generate new Divs with Button on it in order to do something. And I applied the for loop on the button from the guide here Turns out it works! but there's a bug where some buttons wont work whenever I generate more divs+button and I don't know why?

const btnCreate = document.querySelector(".myButton");

const changeBtn = document.getElementsByClassName("changeBtnStyle");
const newNewDiv = document.getElementsByClassName("newCDiv");

const createFunc = function() {

  const parentDiv = document.querySelector(".parentDiv");
  const newDiv = document.createElement("div");
  const newChangeBtn = document.createElement("button");


  parentDiv.appendChild(newDiv);
  newDiv.appendChild(newChangeBtn);

  newDiv.classList.add("newCDiv");
  newChangeBtn.classList.add("changeBtnStyle")
  newChangeBtn.innerHTML = "change"

  for (let i = 0; i < changeBtn.length; i++) {

    changeBtn[i].addEventListener("click", function() {

      newNewDiv[i].classList.toggle("changeColor");

    }, false);
  }


};


btnCreate.addEventListener("click", createFunc);
.parentDiv {
  margin: auto;
  width: 300px;
  height: 300px;
  background-color: gray;
  position: relative;
}

.newCDiv {
  background: green;
  width: 50px;
  height: 50px;
  position: relative;
}

.changeBtnStyle {
  position: absolute;
}

.changeColor {
  background: red;
}

.myButton {
  margin: auto;
}
<button class="myButton">
    Create Div w/ Button
  </button>
<div class="parentDiv">


</div>

Here's the JSFiddle one

Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
Louein
  • 45
  • 6
  • 2
    The problem is that you add event listeners to ALL buttons every time you create a button. When you add it twice, it'll trigger the function twice (turn green and turn back to red, making it seem like it's not working). You only need to add an event listener to the newly created button. No need to loop through them all. – ippi Mar 21 '21 at 17:55

1 Answers1

1

Every time you click on a generated button the for loop will add an event listener for each button. Even the ones that already have an event listener attached to them. So by doing that and then toggling the class, you call the classList.toggle() function more than once.

For example with 1 event listener, the toggle works fine. But with 2 event listeners you toggle and toggle again, resulting in an immediate on / off switch. 3 event listeners will toggle 3 times, on / off / on, having the right resulting but not working correctly.

So instead of looping each button again, just add the event listener only to the element that you've created in the createFunc function.

const btnCreate = document.querySelector(".myButton");

const changeBtn = document.getElementsByClassName("changeBtnStyle");
const newNewDiv = document.getElementsByClassName("newCDiv");

const createFunc = function() {
  const parentDiv = document.querySelector(".parentDiv");
  const newDiv = document.createElement("div");
  const newChangeBtn = document.createElement("button");

  parentDiv.appendChild(newDiv);
  newDiv.appendChild(newChangeBtn);

  newDiv.classList.add("newCDiv");
  newChangeBtn.classList.add("changeBtnStyle")
  newChangeBtn.innerHTML = "change"

  newChangeBtn.addEventListener("click", function() {
    newDiv.classList.toggle("changeColor");
  }, false);
};


btnCreate.addEventListener("click", createFunc);
.parentDiv {
  margin: auto;
  width: 300px;
  height: 300px;
  background-color: gray;
  position: relative;
}

.newCDiv {
  background: green;
  width: 50px;
  height: 50px;
  position: relative;
}

.changeBtnStyle {
  position: absolute;
}

.changeColor {
  background: red;
}

.myButton {
  margin: auto;
}
<button class="myButton">Create Div w/ Button</button>
<div class="parentDiv"></div>
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32
  • Edit: This works! thanks! I just only need to get the Name of the button within the function then remove the loop – Louein Mar 22 '21 at 00:20
  • I don't see a name in your code. Could you elaborate? – Emiel Zuurbier Mar 22 '21 at 08:55
  • I declared a name changeBtn and newNewDiv outside the createFunc (which is the one who's generating Button and Div). At first, I used them, which is also caused the problem, instead of using them, I use the names newChangeBtn and newDiv within the function and removed the loop and array brackets – Louein Mar 23 '21 at 02:13