I have a parent DIV called workspace and it contains a child DIV called test1. When the DIV test1 is clicked, 3 new DIVs are created dynamically. These 3 DIVs belong to a CSS class called handle and they will be removed from the DOM when the grandparent DIV (workspace) is clicked. I’m trying to add an eventlistener to each of the 3 DIVs using their class name and Bubbling but it is not working.
It works if I give each of the DIVs an ID, get all of them in an array using querySelectorAll with their class name, loop through the array, and finally identify which element is clicked using their IDs before adding the eventlistener in if statements. However I would like to use Bubbling instead of loop to add eventlisteners. If you are wondering why I used their IDs it is because I want each of the three DIVs to have a different behavior when they are clicked, dragged, etc. Please see my code on jsfiddle here.
I created an online trivia game, but I think the following might help you out a little?
First I create the question and answers by populating the with data (I don’t know exactly what you are doing, so populating with data could be ignored? ) -
/* Populate Question, Create Answer Buttons */
const createQuiz = (gameData) => {
startTimer(dSec);
question.textContent = gameData.question;
/*
* Create Buttons then insert answers into buttons that were
* create.
*/
gameData.answers.forEach((value, index) => {
let gameButton = buttonContainer.appendChild(d.createElement('button'));
gameButton.id = 'answer' + (index + 1);
gameButton.className = 'answerButton';
gameButton.setAttribute('data-correct', (index + 1).toString());
gameButton.addEventListener('click', clickHandler, false);
/*
* Don't Show Answers that have a Blank Field
*/
if (value !== "") {
gameButton.appendChild(d.createTextNode("📷 " + value));
} else {
gameButton.appendChild(d.createTextNode(" "));
gameButton.style.pointerEvents = "none"; // Disable Click on Empty Field
}
});
};
Then after the user has answer, I need to reset the question and answers -
Hi m3g4p0p,
Thanks for your reply. Good catch I was using the variable div1 instead of the id d1 but that’s only part of the problem. The element d1 is created along with the elements d2 and d3 after clicking on the parent div (test1). I noticed that ev.target.id doesn’t change to (d1) when I click on it and instead it still points to the parent (test1).
Hi dennisjn, Thanks for your reply. I noticed that I forgot to create the global variable originalEl which throws an error but it had the unexpected side effect of correctly displaying the id of the clicked element some of the time.
After creating the global variable originalEl it no longer throws an error but when I click on the test1 DIV and then click on the DIVs d1, d2, or d3, ev.target.id kept pointing to the id of test1 even though I added false as the last argument of addEventListener as you have suggested.
Ah yes sry forgot to mention that… you probably forgot to add "use strict" in your original code. ;-) Anyway here’s the fork of your fiddle where the above screencast was taken from:
BTW you can indeed omit the useCapture parameter here as false is the default.
The first click on the Test 1 box and the alert reported “test1” as expected.
I then clicked on the middle box and the alert reported “d2”
You are using outdated code, you should use at least ES6.
You should also use strict equality that is if(x === y) and if(x !== y) This could be where your problem is.
If the problem is adding click event handlers to the three div elements created in the addHandles() function, then add them as you create the div elements.
You have the option to create the click handler as a separate function and attach it to all three div elements or you could create separate listener functions for each div element.
Hi dennisjn,
Thanks for your help. I will surely use some of your suggestions in my final code. The purpose of this exercise was to flesh out adding event listeners to dynamically added elements via the use of event bubbling then resolve any issue that may arise. Sure enough there were many issues I needed to resolve.
I refactored my code and added only the basic code for various events just enough to allow me to see what’s going on. I removed the mousedown event listener from the body of the click event listener and placed it outside of the click event listener. The issue now is the the mousedown event conflicts with the click event causing the click event to not work.
Well it does not conflict with the click event per se – it’s only the alert() modal blocking the UI after the mouse down event, so the click event will never fire. If you replace the alert()s with console.log()s it works though: