简体   繁体   English

在javascript中更改其子级复选框后,如何从父级List-item(li)添加/删除类?

[英]How to add/remove class from a parent List-item(li) when their child checkbox is changed in javascript?

I am building a simple Todo app in Javascript but I got stuck trying to add/remove a class to a List-item(li) that is the parent of a checkbox. 我正在用Javascript构建一个简单的Todo应用程序,但是在尝试将类添加到作为复选框父级的List-item(li)时遇到了麻烦。

By default a list-item (Todo) checkbox is unchecked (with no class added). 默认情况下,未选中列表项(Todo)复选框(未添加任何类)。 Whenever a user check a todo checkbox, a class is added, and the todo text gets a line through. 每当用户选中待办事项复选框时,都会添加一个类,并且待办事项文本会通过一行。

I managed to make it work but nothing happens. 我设法使其正常工作,但没有任何反应。

 // ADD ITEM, REMOVE ITEM - FUNCIONALITY const btn = document.getElementById('btn'); const ulList = document.getElementById('list'); // Button event listener with adding li elemnts with input value btn.addEventListener('click', function() { var input = document.getElementById('input').value; // Capture input value var newItem = document.createElement("LI"); // Create a <li> node newItem.innerHTML = input + '<input type="checkbox" class="checkboxes" ><p class="delet">x</p>'; // Add content to li element for todo. ulList.insertBefore(newItem, ulList.childNodes[0]); // Insert <li> before the first child of <ul> // input = ' '; // Reset input value to empty field // Remove item funcionality newItem.childNodes[2].onclick = function() { this.parentNode.remove(this); } }) // ********** IMPORTANT CODE BELOW *********************** // MARK DONE TODO - FUNCIONALITY var checkBox = document.getElementsByClassName('checkboxes'); for (var i = 0; i < checkBox; i++) { checkBox[i].addEventListener('change', function() { if (this.checked) { // Checkbox is checked.. this.parentNode.classList.add("line-through"); } else { // Checkbox is not checked.. this.parentNode.classList.remove("line-through"); } }); } 
 .line-through { text-decoration: line-through; } 
 <p class="lead text-center">Welcome to my todoList applications</p> <div class="row"> <form id="form" class="col-lg-6 col-8 mx-auto"> <div class="input-group"> <input type="text" id="input" class="form-control"><span> <button id="btn" type="button" class="btn btn-primary">Submit</button></span> </div> </form> </div> <div class="row"> <ul id="list" class="list col-lg-6 col-8 mx-auto"> <!-- <li>this is a todo item <input type="checkbox" class="checkbox"></li> <li>this is a todo item <input type="checkbox" class="checkbox"></li> --> </ul> </div> <div class="row"> <button id="btnClr" type="button" class="btn btn-primary mx-auto btnHide">Clear All Todos</button> </div> 

I would appreciate any help. 我将不胜感激任何帮助。 Thanks in advance everyone! 预先感谢大家! :) :)

A complete and working example below. 下面是一个完整且有效的示例。 Generally speaking, it is easier (for me, but your personal experiences may vary) to utilize document.createElement instead of .innerHTML for tasks like yours, because attaching event listeners to elements created by document.createElement is (again, in my opinion) much easier. 一般来说,对我这样的任务来说,使用document.createElement而不是.innerHTML更容易(对我来说,您的个人经历可能会有所不同),因为(再次,将事件侦听器附加到由document.createElement创建的元素上)容易得多。

The example creates a new <li> , <input type="checkbox"> , <span> (for the todo's title) and a <button> (for deleting the todo) whenever the "Submit" button is clicked. 只要单击“提交”按钮,该示例就会创建一个新的<li><input type="checkbox"><span> (用于待办事项的标题)和一个<button> (用于删除待办事项)。 After all inner elements are created, they are easy to append to the <li> with .appendChild . 创建所有内部元素之后,可以轻松地使用.appendChild将它们添加到<li>

I tried to use descriptive names, so following along shouldn't be complicated. 我尝试使用描述性名称,因此遵循起来应该并不复杂。

 const todoAddBtn = document.getElementById('btn'); const todoDeleteBtn = document.getElementById('btnClr'); const todosList = document.getElementById('list'); const todoInput = document.getElementById('input'); todoAddBtn.addEventListener('click', function(){ const todoTopic = readAndClearValue(todoInput); const todoLi = createListItem(); const todoCheckbox = createCheckbox(); const todoTitle = createTitle(todoTopic); const todoDelete = createDeleteButton(); todoLi.appendChild(todoCheckbox); todoLi.appendChild(todoTitle); todoLi.appendChild(todoDelete); todosList.insertBefore(todoLi, todosList.firstElementChild); }); todoDeleteBtn.addEventListener('click', function () { todosList.innerHTML = ''; }); // readAndClearValue :: HTMLElement -> String function readAndClearValue (element) { const value = element.value; element.value = ''; return value; } // createListItem :: () -> HTMLElement function createListItem () { return document.createElement('li'); } // createTitle :: String -> HTMLElement function createTitle (text) { const title = document.createElement('span'); title.textContent = text; return title; } // createDeleteButton :: () -> HTMLElement function createDeleteButton () { const button = document.createElement('button'); button.textContent = 'X'; button.className = 'delet'; button.addEventListener('click', function () { button.parentNode.removeChild(button); // to remove the <li>, use something like // button.parentNode.parentNode.removeChild(button.parentNode) // or button.closest('li').remove() if supported }); return button; } // createCheckbox :: () -> HTMLElement function createCheckbox () { const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.className = 'checkboxes'; checkbox.addEventListener('change', function () { if (checkbox.checked) { checkbox.parentNode.classList.add('line-through'); } else { checkbox.parentNode.classList.remove('line-through'); } }); return checkbox; } 
 .line-through { text-decoration: line-through; } 
 <p class="lead text-center">Welcome to my todoList applications</p> <div class="row"> <form id="form" class="col-lg-6 col-8 mx-auto"> <div class="input-group"> <input type="text" id="input" class="form-control" > <button id="btn" type="button" class="btn btn-primary">Submit</button> </div> </form> </div> <div class="row"> <ul id="list" class="list col-lg-6 col-8 mx-auto"> </ul> </div> <div class="row"> <button id="btnClr" type="button" class="btn btn-primary mx-auto btnHide"> Clear All Todos </button> </div> 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <style>
        .line-through li {
            text-decoration: line-through;
        }
    </style>
</head>
<body>
<p class="lead text-center">Welcome to my todoList applications</p>
<div class="row">
    <form id="form" class="col-lg-6 col-8 mx-auto">
        <div class="input-group">
            <input type="text" id="input" class="form-control" ><span>
        <button id="btn" type="button" class="btn btn-primary">Submit</button></span>
        </div>
    </form>
</div>
<div class="row">
    <ul id="list" class="list col-lg-6 col-8 mx-auto">
        <!-- <li>this is a todo item <input type="checkbox" class="checkbox"></li>
              <li>this is a todo item <input type="checkbox" class="checkbox"></li> -->
    </ul>
</div>
<div class="row">
    <button id="btnClr" type="button" class="btn btn-primary mx-auto btnHide">Clear All Todos</button>
</div>
</body>
<script>
    // ADD ITEM, REMOVE ITEM - FUNCIONALITY
    const btn = document.getElementById('btn');
    const ulList = document.getElementById('list');
    let checkBox = document.querySelectorAll('.checkboxes li');


    // Button event listener with adding li elemnts with input value
    btn.addEventListener('click', function(){
        var input = document.getElementById('input').value; // Capture input value
        var newItem = document.createElement("LI");     // Create a <li> node
        newItem.innerHTML = input + '<input type="checkbox" class="checkboxes" ><p class="delet">x</p>';  // Add content to li element for todo.
        ulList.insertBefore(newItem, ulList.childNodes[0]);  // Insert <li> before the first child of <ul>
        // input = ' ';  // Reset input value to empty field

        // Remove item funcionality
        newItem.childNodes[2].onclick = function() {this.parentNode.remove(this);}
    });

    // ********** IMPORTANTO CODE BELOW ***********************
    // MARK DONE TODO  - FUNCIONALITY


    document.body.addEventListener( 'click', function ( event ) {
        if (event.srcElement.className == 'checkboxes') {

                console.log(this);
                this.classList.toggle('line-through');

        }
    });

    checkBox.forEach(el => {
        el.addEventListener('change', myFunction);
    }, false);

    function myFunction(){
        if(this.checked) {
            console.log('here')
            this.classList.toggle('line-through');
        }
    }
</script>
</html>

Seems like you need to add listeners after checkbox creation. 似乎您需要在创建复选框后添加侦听器。 Shat's happening now You load the page and at the start, you don't have any checkbox, so when you run for loop no handlers attached 现在发生了问题加载页面,并且在开始时没有任何复选框,因此在运行for循环时不附加任何处理程序

Here is a sniped of how to make it work. 这里是如何使其工作的片段。 There are a lot of changes but I've tried to leave detailed comments. 有很多更改,但我尝试留下详细的评论。

Feel free to ask if you have any questions :) 随时询问您是否有任何问题:)

https://codesandbox.io/embed/bootstrap-r3ud0 https://codesandbox.io/embed/bootstrap-r3ud0

Also here is JS part. 这也是JS部分。

 const btn = document.getElementById("btn"); const ulList = document.getElementById("list"); // Button event listener with adding li elemnts with input value btn.addEventListener("click", function() { var input = document.getElementById("input").value; // Capture input value var newItem = document.createElement("LI"); // Create a <li> node // manually create input element var inputEl = document.createElement("input"); // set attributes inputEl.type = "checkbox"; inputEl.class = "checkboxes"; // also create p element var xmark = document.createElement("p"); xmark.innerHTML = "x"; xmark.class = "delet"; // set click handler xmark.onclick = function() { this.parentNode.remove(this); }; // most important part! // we add change listener on input create step inputEl.addEventListener("change", changeHandler); newItem.innerHTML = input; // and append our new elements to the li newItem.appendChild(inputEl); newItem.appendChild(xmark); ulList.insertBefore(newItem, ulList.childNodes[0]); // Insert <li> before the first child of <ul> }); // create separate handler for change event (first param is event) const changeHandler = event => { // we can access checked property of an element const checked = event.target.checked; // also we need the target (input in this case) for further manipulations const element = event.target; if (checked) { // Checkbox is checked.. element.parentNode.classList.add("line-through"); } else { // Checkbox is not checked.. element.parentNode.classList.remove("line-through"); } }; 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 单击子 li 时将类删除/添加到父 div - remove/add class to parent div when child li is clicked 当子LI具有“ item_active”时,将类“ item_active”添加到父LI - Add class “item_active” to parent LI when a child LI has “item_active” 当我在父项上选择一个项目时,如何在其上添加活动类。 使用javascript - how do i add an active class on the parent li when i select an item on it. using javascript 如何使用javascript在li第一个孩子上添加或删除类 - how to add or remove class on li first child using javascript 使用 removeClass 从列表项点击锚链接中删除类 - Remove class from list-item on-click anchor link with removeClass 如何使用Angular.js添加/删除列表项onClick? - How do I add/remove a list-item onClick using Angular.js? 使用普通 javascript 根据最高 li 动态设置与列表项 ( li ) 相等的高度 - Dynamically set equal height to list-item ( li ) as per tallest li using plain javascript 如何使用 JavaScript 在单击时将 CSS styles 添加到列表元素,但在单击另一个 li 项目时将其删除? - How can I use JavaScript to add CSS styles to a list element when clicked, but remove it when another li item is clicked? 选择子li时如何将父li类设置为活动状态 - How to set the parent li class to active when child li is selected 如何为父项添加样式 <li> 儿童项目 <ul> 存在吗? - How to add style to parent <li> item if child <ul> exists?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM