I have n number of buttons with id="btn-delete". I get all the buttons using document.querySelectorAll('#btn-delete') and iterate over each button to add "addEventListener" (click). heres the code.
dl_btn = document.querySelectorAll('#btn-delete')
Array.from(dl_btn).map(el => {
el.addEventListener('click',function(){
const uuid = el.getAttribute('index') //getting the attribute value
deleteTodo(uuid) // call to delete function with uuid (unique id associate to button )
})
})
//Here's the deleteTodo function :
let deleteTodo = function(id){
listTodo = getItems()
let parsedTodos = []
parsedTodos = JSON.parse(listTodo)
const index = parsedTodos.findIndex((ele)=>{
return ele.id == id
})
parsedTodos.splice(index,1)
let stringTodos = JSON.stringify(parsedTodos)
localStorage.setItem('Todos',stringTodos)
newRender() // call to render function to display updated list after deleting a node
}
Problem/issue: As soon as the page is loaded , newRender() function gets called to get list of nodes. Each node is associated with delete button to delete the node. When I click on delete button the node gets deleted as expected and newRender() function gets executed to get the new list. But when I click to delete some other node , it does not get deleted , seems like the deleting functions gets jammed or freeze after getting called one time. After debugging for long time , I found that when i remove the newRender() method from deleteTodo() , it works as expected. But here problem is I want to do realtime updation of the list and not by refreshing the page everytime I hit delete to see the updated result. Please help me out here.
//Heres is the render function
let newRender = ()=> {
let items = getItems()
if(items !== null){
Todo = JSON.parse(items)
console.log(Todo)
document.querySelector('#notes-render').innerHTML = ''
Todo.map((ele,index) => {
const uuid = ele.id;
//creating HTML elements
let div = document.createElement('div')
let button = document.createElement('button')
let npara = document.createElement('span')
let checkbox = document.createElement('input')
let br = document.createElement('br')
//adding css classes
button.setAttribute('id','btn-delete')
div.setAttribute('id','todo-div')
npara.setAttribute('id','para')
checkbox.setAttribute('id','check-btn')
//setting custom attribute
button.setAttribute('index',uuid)
npara.innerHTML = `${ele.title}`
button.textContent = 'delete'
checkbox.setAttribute('type','checkbox')
document.querySelector('#notes-render').appendChild(div)
//displaying HTML element under "div"
div.appendChild(br)
div.appendChild(checkbox)
div.appendChild(npara)
div.appendChild(button)
})
}
}
CodePudding user response:
Event listeners are specific to the instances of DOM elements. Once a DOM element has been removed from the DOM its even listeners are essentially deleted and you cannot expect new elements that are made to have the same event listeners - even if new elements that take the place of the old are of the same type and class or id.
Here in you newRender() function you delete all the old elements, and with them their event listeners:
document.querySelector('#notes-render').innerHTML = ''
So the solution to your issue would be to run the code that assigns the event listeners during each new render.
let newRender = () => {
let items = getItems();
if (items !== null) {
Todo = JSON.parse(items);
console.log(Todo);
document.querySelector('#notes-render').innerHTML = '';
Todo.map((ele, index) => {
const uuid = ele.id;
//creating HTML elements
let div = document.createElement('div');
let button = document.createElement('button');
let npara = document.createElement('span');
let checkbox = document.createElement('input');
let br = document.createElement('br');
//adding css classes
button.setAttribute('id', 'btn-delete');
div.setAttribute('id', 'todo-div');
npara.setAttribute('id', 'para');
checkbox.setAttribute('id', 'check-btn');
//adding event listeners (