简体   繁体   中英

Adding event listeners to dynamically added list elements

I am very new to JavaScript programming and I am trying to learn event handlers in JavaScript. I am adding event handler on dynamically created elements. I made a simple shopping list code by which I am able to enter the data into the list, and i added a delete icon on right of each item.I added event handler on that icon but it works only for item already on list not on the dynamically added ones.

I tried to figure out ways, for around a day but still couldn't figure out the correct way to achieve this with pure JavaScript . I have gone through almost every answer on stack overflow and many other resources, but still couldn't achieve the solution, i took help of one of the answers on stack overflow while figuring out the solution, which is pure JavaScript,

question link: add event listener on elements created dynamically

the question is similar to mine, but i tried as the answer says, but still not working for me.

document.querySelector("ul").addEventListener('click', function(event) {
    if (event.target.tagName === "I") {
        alert("hmm.. you clicked.");
    }
});

fiddle link: https://jsfiddle.net/65erpycb/

 var input = document.getElementById("userinput"); var enter = document.getElementById("enter"); var ul = document.querySelector("ul"); var listItem = document.querySelectorAll("li"); function toggleFunction(e) { if(e.target.tagName === "LI") { e.target.classList.toggle("done"); } } function addListItemOnClick() { if (input.value.length > 0) { console.log(input.value.length); var li = document.createElement("li"); li.appendChild(document.createTextNode(input.value)); ul.appendChild(li); input.value = ""; var d = document.createElement("div"); d.classList.add("fas", "fa-trash"); li.appendChild(d); } } function addListItemOnPress() { if (input.value.length > 0 && event.keyCode === 13) { var li = document.createElement("li"); li.appendChild(document.createTextNode(input.value)); ul.appendChild(li); input.value = ""; var d = document.createElement("div"); d.classList.add("fas", "fa-trash"); li.appendChild(d); } } enter.addEventListener("click", addListItemOnClick); input.addEventListener("keypress", addListItemOnPress); ul.addEventListener("click",toggleFunction); document.querySelector("ul").addEventListener('click', function(event) { if (event.target.tagName === "I") { alert("hmm.. you clicked."); } }); 
 .box { text-align: center; border: 2px solid black; } h1 { font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif; font-size: 50px; } #first { font-size: 25px; font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; text-decoration: underline; } ul { border: 1px solid black; padding: 0; } li { display: block; list-style: none; font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; font-size: 15px; text-align: center; text-decoration: underline; } #userinput { text-align: center; } .done { text-decoration: line-through; } .fa-trash { float: right; } 
 <!DOCTYPE html> <html> <head> <title>Javascript + DOM</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div class="box"> <h1>Shopping List</h1> <p id="first">Get it done today</p> <input id="userinput" type="text" placeholder="enter items"> <button id="enter">Enter</button> <ul id = "items"> <li>Notebook<i class="fas fa-trash"></i></li> <li>Jello<i class="fas fa-trash"></i></li> <li>Spinach<i class="fas fa-trash"></i></li> <li>Rice<i class="fas fa-trash"></i></li> <li>Birthday Cake<i class="fas fa-trash"></i></li> <li>Candles<i class="fas fa-trash"></i></li> </ul> </div> <script type="text/javascript" src="script.js"></script> <script src="https://kit.fontawesome.com/28803a998e.js"></script> </body> </html> 

I am expecting the delete buttons should also work when i add the items dynamically.

The added items are div tag elements. But the original items are i tag elements. The event.target.tagName === "I" test will only match the i tags, not the div tags.

Update the added items code (in both addListItemOnClick and addListItemOnPress ):

document.createElement("div")

to be:

document.createElement("i")

If you separate data and view and use html-inline binding (which is acceptable for small projects - and similar to templates in angular/react/vue frameworks...) the code will be much more small & clean

 let data=[ { name: "Notebook" }, { name: "Jello" }, { name: "Spinach" }, { name: "Rice" }, { name: "Birthday" }, { name: "Candles" }, ]; function add() { data.push({ name: userinput.value }); userinput.value=''; refresh(); } function del(i) { data.splice(i,1); refresh(); } function refresh() { items.innerHTML = data.map((x,i)=> ` <li>${x.name}<i class="fas fa-trash" onclick="del(${i})"></i></li> `).join(''); } refresh(); 
 <div class="box"> <h1>Shopping List</h1> <p id="first">Get it done today</p> <input id="userinput" type="text" placeholder="enter items"> <button id="enter" onclick="add()">Enter</button> <ul id="items"></ul> </div> <script src="https://kit.fontawesome.com/28803a998e.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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