I’m working on a web page where I have a button with an onclick event listener to switch between dynamically generated elements. The first click works as expected, but after the first click, the event listener doesn’t seem to trigger anymore. Here’s the relevant part of my JavaScript:
document.addEventListener('DOMContentLoaded', function () {
// ... (other initialization code)
trdmDisplayed = 1;
nextbtn = document.querySelector('.nextbtn');
nextbtn.addEventListener('click', function () {
console.log(`trdm when the button is first clicked: ${trdmDisplayed}`);
currentlyDisplayed = document.querySelector(`.indexdiv .shading-div:nth-child(${trdmDisplayed})`);
currentlyDisplayed.style.display = "none";
trdmDisplayed = (trdmDisplayed % 20) + 1;
toDisplay = document.querySelector(`.indexdiv .shading-div:nth-child(${trdmDisplayed})`);
toDisplay.style.display = "block";
});
});
and here is my html:
<div class="movies-container">
{%for movie in movies %}
<div class="shading-div" id="trdm-{{movie.id}}">
/*
other elements...
*/
<div>
<button class="nextbtn" ><i class="fas fa-arrow-right"></i></button>
</div>
</div>
{%endfor%}
</div>
Additional clarification: The dynamically generated elements consist of a fixed set of 20 elements. Upon clicking the button for the first time, the first element successfully transitions from element.style.display = "block"; to "none", and the second element transitions from "none" to "block" as intended and everything is logged onto the console. However, upon clicking the button for the second time, no information is logged to the console, suggesting that the event listener is not being called at all.
I have tried using ChatGPT to find the bug but nothing worked, I’ve revised my javascript many times but still, nothing worked. I’ve inspected my html and my css for any potential errors and could not find any.
2
Answers
Your for loop is creating multiple "next" buttons in your DOM, whereas your
querySelector()
only selects the first one created, so the click event listener is tied to the first button only:That means that when you hide the first "next" button and display the next one, the click event listener won’t be added to the new one you’re displaying, and so the click won’t work.
Instead, have the creation of the next button be outside of your for loop so that you only ever have one and so that you don’t hide it when you hide the one of the generated elements:
On a side note, make sure you declare your variables such as
trdmDisplayed
,nextbtn
andcurrentlyDisplayed
withconst
/let
so that they don’t become global variables and stay scoped to where they’re defined, this will help avoid potentially confusing bugs down the line.Assign button in nextbtn outside of DOM contentloaded listener or remove that listener than check if it works.