I want to have an event that strikes through the text on my li
My HTML
<!DOCTYPE html>
<html>
<head>
<title>Javascript + DOM</title>
<link rel="stylesheet" type="text/css" href="5.3 style.css">
</head>
<body>
<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>
<li class="bold red" random="23">Notebook</li>
<li class="bold red">Jello</li>
<li class="bold red">Spinach</li>
<li class="bold red">Rice</li>
<li class="bold red">Birthday Cake</li>
<li class="bold red">Candles</li>
</ul>
<script type="text/javascript" src="5.2 script.js"></script>
</body>
</html>
My CSS
.done {
text-decoration: line-through;
}
My JS
var list = document.getElementsByTagName("li");
list.addEventListener("click", function(e){
list.classList.toggle("done");
})
I have tried:
var list = document.querySelector("li");
it only gets the first li obviously, so I tried
querySelectorAll
it isn't working it tells me the error:
Uncaught TypeError: Cannot read property 'toggle' of undefined"
I want to have an event that strikes through the text on my li
My HTML
<!DOCTYPE html>
<html>
<head>
<title>Javascript + DOM</title>
<link rel="stylesheet" type="text/css" href="5.3 style.css">
</head>
<body>
<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>
<li class="bold red" random="23">Notebook</li>
<li class="bold red">Jello</li>
<li class="bold red">Spinach</li>
<li class="bold red">Rice</li>
<li class="bold red">Birthday Cake</li>
<li class="bold red">Candles</li>
</ul>
<script type="text/javascript" src="5.2 script.js"></script>
</body>
</html>
My CSS
.done {
text-decoration: line-through;
}
My JS
var list = document.getElementsByTagName("li");
list.addEventListener("click", function(e){
list.classList.toggle("done");
})
I have tried:
var list = document.querySelector("li");
it only gets the first li obviously, so I tried
querySelectorAll
it isn't working it tells me the error:
Share Improve this question edited Jul 11, 2019 at 12:59 Brian Tompsett - 汤莱恩 5,89372 gold badges61 silver badges133 bronze badges asked May 30, 2018 at 12:15 skylarskylar 331 silver badge5 bronze badges 3Uncaught TypeError: Cannot read property 'toggle' of undefined"
-
querySelectorAll()
returns aNodeList
. You already tagged this with jQuery, which makes stuff like this a lot easier. – user5734311 Commented May 30, 2018 at 12:27 - jQuery is fading out and MVC is taking over. It's better to learn the basic IMO – Endless Commented May 30, 2018 at 12:30
- yeah, just the basics that I need to learn. simple event handlers and such. i'll check out on MVC haven't heard about it yet. – skylar Commented May 30, 2018 at 12:37
6 Answers
Reset to default 1You need to attach click
listener to all the li
elements which you get from document.getElementsByTagName("li");
as the getElementsByTagName()
returns you the list of elements with that tag and you need to assign the listener individually to each tag which was missing in your code and hence, error was showing up.
var list = document.getElementsByTagName("li");
for(var i=0; i<list.length; i++){
list[i].addEventListener("click", liClick);
}
function liClick(){
this.classList.toggle("done");
}
.done {
text-decoration: line-through;
}
<!DOCTYPE html>
<html>
<head>
<title>Javascript + DOM</title>
<link rel="stylesheet" type="text/css" href="5.3 style.css">
</head>
<body>
<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>
<li class="bold red" random="23">Notebook</li>
<li class="bold red">Jello</li>
<li class="bold red">Spinach</li>
<li class="bold red">Rice</li>
<li class="bold red">Birthday Cake</li>
<li class="bold red">Candles</li>
</ul>
<script type="text/javascript" src="5.2 script.js"></script>
</body>
</html>
I used document.querySelectorAll
to select all li
tags.
Then iterated over the collection of DOM
objects and attached event to every single one of them.
As you will notice I am using the event inside the click
event listener to toggle the class done
on.
Hope this helps
var list = document.querySelectorAll("li");
for(var i = 0; i < list.length; i++) {
list[i].addEventListener("click", function(e){
e.currentTarget.classList.toggle("done");
})
}
.done {
text-decoration: line-through;
}
<!DOCTYPE html>
<html>
<head>
<title>Javascript + DOM</title>
<link rel="stylesheet" type="text/css" href="5.3 style.css">
</head>
<body>
<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>
<li class="bold red" random="23">Notebook</li>
<li class="bold red">Jello</li>
<li class="bold red">Spinach</li>
<li class="bold red">Rice</li>
<li class="bold red">Birthday Cake</li>
<li class="bold red">Candles</li>
</ul>
<script type="text/javascript" src="5.2 script.js"></script>
</body>
</html>
instead of adding an event to each and every <li>
element add just one event to the <ul>
that watches what you click on, that will help further when you and new todo's to the list
var ul = document.querySelector("ul");
ul.addEventListener("click", function(e){
evt.target.classList.toggle("done");
})
But here you also need to watch out of which element you are clicking on. you might just have clicked on the ul, or a deeper element inside of the li element
Javascript code below:
var list = document.querySelectorAll("li");
for(var i = 0; i < list.length; i++) {
list[i].addEventListener("click", liClick);
}
//function to add the 'line through' style
function liClick() {
this.classList.toggle("done");
}
CSS code below:
.done{
text-decoration: line-through;
}
Html code below:
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="stylejs.css">
</head>
<body>
<h1>Shopping List</h1>
<p id="first">Get is done today</p>
<input id="userinput" type="text" placeholder="enter to-do">
<button id="enter">Enter</button>
<ul>
<li class="bold red" random="23">Notebook</li>
<li>Jello</li>
<li>Spinach</li>
<li>Rice</li>
<li>Birthday cake</li>
<li>Candles</li>
</ul>
<script type="text/javascript" src="learndom.js"></script>
</body>
</html>
I know you found your answer, but let me show you a cleaner way to do this:
function toggleClassDoneOnAndOff(event) {
if (event.target.tagName === "LI") {
event.target.classList.toggle("done");
}
}
ul.addEventListener("click", toggleClassDoneOnAndOff);
Hope you enjoy that :)
I used document.querySelectorAll
to click on the ul>li
element.
This is the code I am using (I hope this helps):
// Toggle list items on and off when clicked on
var list = document.querySelectorAll('ul>li');
for (var i = 0; i < list.length; i++) {
list[i].addEventListener("click", toggleList);
}
// function to add the 'line-through' (Strike-through) style
function toggleList(event) {
event.target.classList.toggle("done"); // or this.classList.toggle("done");
}
.done {
text-decoration: line-through;
}
<!DOCTYPE html>
<html>
<head>
<title>Javascript + DOM</title>
<link rel="stylesheet" type="text/css" href="5.3 style.css">
</head>
<body>
<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="list">
<li class="bold red" random="23">Notebook</li>
<li class="bold red">Jello</li>
<li class="bold red">Spinach</li>
<li class="bold red">Rice</li>
<li class="bold red">Birthday Cake</li>
<li class="bold red">Candles</li>
</ul>
<script type="text/javascript" src="5.2 script.js"></script>
</body>
</html>