So I have a simple script that adds "li" elements to the "ul" and assigns them a class. Now I want to change the class of "li" item on click event.
Here is the HTML:
<form class="form">
<input id="newInput" type="text" placeholder="Dodaj pozycję">
<button id="createNew" type="button">Dodaj</button>
</form>
<h2>Moja lista:</h2>
<div class="listBg">
<ul id="list">
</ul>
</div>
<button id="deleteAll" type="button">Wyczyść</button>
And JS:
function addItem() {
var myList = document.getElementById("list"); // get the main list ("ul")
var newListItem = document.createElement("li"); //create a new "li" element
var itemText = document.getElementById("newInput").value; //read the input value from #newInput
var listText = document.createTextNode(itemText); //create text node with calue from input
newListItem.appendChild(listText); //add text node to new "li" element
if (itemText === "") { // if input calue is empty
alert("Pole nie może być puste"); // show this alert
} else { // if it's not empty
var x = document.createElement("span"); // create a new "span" element
x.innerText = "X"; // add inner text to "span" element
x.className = "closer"; // add class to "span" element
myList.appendChild(newListItem); // add created "li" element to "ul"
newListItem.className = "item"; // add class to new "li" element
newListItem.appendChild(x); // add a "span" to new "li" element
var itemText = document.getElementById("newInput"); // read current input value
itemText.value = ""; // set current input calue to null
}
};
I was thinking something like this should do the trick, but it's not working:
function itemDone() {
var listItems = document.querySelectorAll("li");
var i;
for (i = 0; i < listItems.length; i++) {
listItem[i].className = "itemDone";
};
};
var item = document.getElementsByClassName("item");
item.addEventListener("click", itemDone);
I'm fairly new to javascript so I would appreciate some explanation with the answer.
Use event delegation for the dynamically created elements. With this, you only need one event listener on the ul#list
and it will work for all elements you dynamically attach to it:
document.getElementById("list").addEventListener("click",function(e) {
if (e.target && e.target.matches("li.item")) {
e.target.className = "foo"; // new class name here
}
});
Here's a simplified example so you can see what happens with the code:
function addItem(i) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(i));
li.className = 'item';
document.getElementById('list').appendChild(li);
}
var counter = 2;
document.getElementById('btn').addEventListener('click', function() {
addItem(counter++);
});
document.getElementById("list").addEventListener("click", function(e) {
if (e.target && e.target.matches("li.item")) {
e.target.className = "foo"; // new class name here
alert("clicked " + e.target.innerText);
}
});
<ul id="list">
<li class="item">1</li>
</ul>
<button id="btn">
add item
</button>
You'll have to set the eventListener on each single item, as document.getElementsByClassName()
returns a collection of items and you can't simply add an event listener to all of them with one call of addEventListener()
.
So, just like the loop you used in itemDone()
, you'll have to iterate over all items and add the listener to them:
var items = document.getElementsByClassName("item");
for (var i = 0; i < items.length; i++) {
items[i].addEventListener("click", itemDone);
}
As pointed out in the comments, you can also do so directly when creating the elements, so in your addItem()
function, add:
newListItem.addEventListener("click", itemDone);
try this :
var item = document.getElementsByClassName("item");
for (var i = 0; i < item.length; i++) {
item[i].addEventListener("click", itemDone);
}
function addItem(i) {
var li = document.createElement('li');
li.appendChild(document.createTextNode(i));
li.className = 'item';
document.getElementById('list').appendChild(li);
}
var counter = 2;
document.getElementById('btn').addEventListener('click', function() {
addItem(counter++);
});
document.getElementById("list").addEventListener("click", function(e) {
if (e.target && e.target.matches("li.item")) {
e.target.className = "foo"; // new class name here
alert("clicked " + e.target.innerText);
}
});
<ul id="list">
<li class="item">1</li>
<li class="item">1</li>
<li class="item">1</li>
<li class="item">1</li>
<li class="item">1</li>
</ul>
<button id="btn">
add item
</button>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With