简体   繁体   中英

add strikethrough for dynamically created lis

I can make an li created in my html file have a strike through when clicked, but I can't get it the dynamically created ones to work... Any advice would be greatly appreciated!

<!DOCTYPE html>
<html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To do</title>
    <link rel="stylesheet" href="todo.css">
    <script src="https://kit.fontawesome.com/ff289d152e.js" crossorigin="anonymous"> 
    </script>
    </head>
<body>

        <div class="container">
        <h1>To be done</h1>
            <input id="add-todo" type="text" placeholder="What do you have to do?">
        <ol id="tasks">
            <li>
               This one works <i class="fas fa-trash-alt"></i>
            </li>
        </ol> 
    </div>
<script type="text/javascript" src="todo.js"></script>   
</body>
</html>

html {
    box-sizing: border-box;
    height: 100vh;
    width: 100vw;
}
body{
    font-family: 'Raleway';
    background: url(https://i.gyazo.com/9024e4cc2d29408dd08bd67a54b355c8.png);
    background-size: cover;
    background-position: center;
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    width: 100%;
    height: 100%;
}

.container {
    display: flex;
    flex-direction: column;
    background-color: gray;
    margin: 10px;
    padding: 10px;
}

Add this style when clicked...

.completed {
    text-decoration: line-through;
}

i {
    margin-left: 20px;
}

let addTaskField = document.getElementById('add-todo');
let tasks = document.getElementById('tasks');
let todos = document.querySelectorAll("li");




// create a todo
addTaskField.addEventListener('keypress', function(event){
if(event.which === 13 && this.value != ''){
    let li = document.createElement("li");
    let i = document.createElement("i");
    i.classList = "fas fa-trash-alt";
    li.innerHTML = this.value;
    li.appendChild(i);
    tasks.append(li);
    this.value = '';
}
});

Can't I just select all lis, even if they're created later, and loop through them adding the event listener?

// add strikethrough
todos.forEach(function(todo) {
    todo.addEventListener('click', function() {
        this.classList.toggle('completed');
    });
})

If you check your 'todos' variable, it only has one 'li' element in it at all times. No matter how many new tasks you add. This is because todos('s) value get's updated when the page loads for the first time.

All I did is added the event listener before the 'li' get's appended. It's not the most elegant solution but it works. If you run this you'll notice it works only for the dynamically created elements.

let addTaskField = document.getElementById('add-todo');
let tasks = document.getElementById('tasks');
let todos = [];

// create a todo
addTaskField.addEventListener('keypress', function(event){
if(event.which === 13 && this.value != ''){
    let li = document.createElement("li");
    let i = document.createElement("i");
    i.classList = "fas fa-trash-alt";
    li.innerHTML = this.value;
    li.appendChild(i);
    li.addEventListener('click', function() {
        this.classList.toggle('completed');
    })
    tasks.append(li);
    todos = document.querySelectorAll("li");
    this.value = '';
}
});

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