Adding event listeners to <li> that are created using javascript

Deadly 提交于 2020-06-26 12:13:32

问题


I am quite new to manipulating elements in the DOM in JS so I am creating a simple to do list to get more comfortable and where I can add items using the input and remove items by clicking on the list item. ALthough this may not be best practice and limitting I am just wanting to use create and remove elements rather than using objects or classes until I get more familar, also using plain/vanilla js so please keep this in mind when answering.

I am trying to add a click event which removes the <li> when the <li> is clicked.

My logic is... When the page is loaded I can't just run a for loop over all of the <li>s and add event handlers as all of the <li>'s do not exist yet. So my attempted solution is when the addTaskButton event is triggered, we get all of the <li> that are on the page at the time of the event, we loop through all of them and add an eventlistener to <li>'s that are waiting to be removed when clicked.

This doesn't seem to work and may be overly complicated.

Can someone please explan to me very simply like I'm 5 why this doesn't work or what a better way to do this would be?

Thank you in advance

HTML

<ul id="taskList">
    <li>example</li>

</ul>
<input type="text" id="addTaskInput">
<button id="addTaskButton">Add Task</button>

JavaScript

const taskList = document.querySelector("#taskList");
const addTaskInput = document.querySelector("#addTaskInput");
const addTaskButton = document.querySelector("#addTaskButton");
let taskItem = document.querySelectorAll("li");


addTaskButton.addEventListener("click", () => {
    let taskItem = document.createElement("li");
    taskItem.textContent = addTaskInput.value;
    for (let i = 0; i < taskItem.length; i++) {     
        taskItem[i].addEventListener("click", () => {
            let taskItem = document.querySelectorAll("li");
            taskList.removeChild(taskItem[i]);      
        });
    }
    taskList.appendChild(taskItem);
    addTaskInput.value = " ";
});

回答1:


Here is code i created for your requirement, this implement jQuery $(document).on mechanism in vanilla javascript, now where ever you create an li inside the document, on clicking that li it will be removed.

Explaination

What it does is on clicking the document it checks on which element is clicked (e.target is the clicked element, e is is the click event on document), then checks if the clicked item is an li tag (e.target.tagName will tell us the tag name if the item clicked), so if it is an li just remove it;

	const taskList = document.querySelector("#taskList");
	const addTaskInput = document.querySelector("#addTaskInput");
	const addTaskButton = document.querySelector("#addTaskButton");


	addTaskButton.addEventListener("click", () => {
	    let taskItem = document.createElement("li");
	    taskItem.textContent = addTaskInput.value;
	    taskList.appendChild(taskItem);
	    addTaskInput.value = " ";
	});

	document.onclick = function(e)
	{
	  if(e.target.tagName == 'LI'){
	     e.target.remove();
	   }
	}
<ul id="taskList">
    <li>example</li>

</ul>
<input type="text" id="addTaskInput">
<button id="addTaskButton">Add Task</button>



回答2:


Update your for loop like so:

for (let i = 0; i < taskItems.length; i++) {     
    taskItems[i].addEventListener("click", () => 
        taskList.removeChild(taskItems[i]);      
    });
}

Also your initial taskItem variable should be taskItems and is reflected in the for loop above.




回答3:


taskList.addEventListener("click", (event) => {
     event.target.remove();
});

When the specified event occurs the event object is returned. The event object has several properties, one of them being target which is the element which is the element which the event occured on. event.target is returned to us and we are applying the remove() method to event.target

because of event "bubbling" or "Event Propagation", we can attach the event handler to an ancestor. It's best to attach the event listener to the closest ancestor element that is always going to be in the DOM (won't be removed).

When an event is triggered-in this case the "click" event. All decending elements will be removed - which in our case as there are only <li>'s this would be fine. But we should be more specific as in a different case we could be attaching this event handler to a div which has several different elements.

To do this we add an if condition to check that the tagName is an <li>

if (event.target.tagName == "LI") 

note that the element must be calpitalised

Solution is as follows

taskList.addEventListener("click", (event) => {

      if(event.target.tagName == "LI"){
         event.target.remove();
    }});

Further reading:

Event object and its properties: https://developer.mozilla.org/en-US/docs/Web/API/Event

Event Bubbling: https://developer.mozilla.org/en-US/docs/Web/API/Event/bubbles

tagName: https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName



来源:https://stackoverflow.com/questions/46031451/adding-event-listeners-to-li-that-are-created-using-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!