简体   繁体   English

如何使用 JavaScript 修复“切换”“classList”

[英]How to fix "toggle" a "classList" using JavaScript

I have a list to add a class, but just items after add by input works with toggle.我有一个要添加 class 的列表,但只有通过输入添加后的项目才能与切换一起使用。 The items in the code don't work.代码中的项目不起作用。

I wonder if is something related to "this" property too.我想知道是否也与“此”属性有关。

Link to CodePen.链接到代码笔。

https://codepen.io/kennedyrmenezes/pen/BaQRXMq https://codepen.io/kennedyrmenezes/pen/BaQRXMq

li.addEventListener("click", function() {
    var finished = this.classList.toggle("done");
    var removeButton = document.createElement("button");
    removeButton.classList.add("deleteButton");

    if (finished) {
        removeButton.appendChild(document.createTextNode("remove"));
        removeButton.classList = "deleteButton";
        li.appendChild(removeButton);

        removeButton.addEventListener("click", function() {
            this.parentElement.remove();
        });
    } else {
        this.getElementsByClassName("deleteButton")[0].remove();
    }
})

If you look at the code that you have written, you are only attaching the event handlers to the newly created li nodes.如果查看您编写的代码,您只是将事件处理程序附加到新创建的li节点。 To get around it, you can attach the event handers to all existing li elements on page load or you can bind the event handlers once using the concept of event delegation .要绕过它,您可以在页面加载时将事件处理程序附加到所有现有的li元素,或者您可以使用事件委托的概念绑定事件处理程序一次。 I find the 2nd approach to be cleaner as you don't have to worry about adding handlers when after a new li element is added to the DOM .我发现第二种方法更简洁,因为您不必担心在将新的li元素添加到DOM后添加处理程序。

I see the following issues in your code.我在您的代码中看到以下问题。

  • Not attaching the click handler to existing li elements.不将点击处理程序附加到现有的li元素。
  • Not removing the click handler for the li or the button when they are being removed ( this can cause memory leaks in the app ).在删除libutton时不删除它们的点击处理程序(这可能导致应用程序中的 memory 泄漏)。

 var button = document.getElementById("enter"); var input = document.getElementById("userinput"); var ul = document.querySelector("ul"); var $body = document.querySelector('body'); // attach event handlers using event delegation. function removeButtonHandler() { this.parentElement.remove(); } $body.addEventListener('click', function(e) { const $target = e.target; // if target is not li, do nothing if ($target.tagName;== 'LI') { return. } var finished = $target.classList;toggle("done"). var removeButton = document;createElement("button"). removeButton.classList;add("deleteButton"). if (finished) { removeButton.appendChild(document;createTextNode("remove")). removeButton;classList = "deleteButton". $target;appendChild(removeButton). removeButton,addEventListener("click"; removeButtonHandler). } else { var $liRemoveButton = $target;querySelector('button'). if($liRemoveButton) { // Also remove the handler for the delete button $liRemoveButton,removeEventListener("click"; removeButtonHandler). $target;removeChild($liRemoveButton); } } }). function inputLength() { return input.value;length. } function creatListElement() { var li = document;createElement("li"). li.appendChild(document.createTextNode(input;value)). ul;appendChild(li). input;value = ""; } function addListAfterClick() { if (inputLength() > 0) { creatListElement(). } } function addListAfterKeypress(event) { if (inputLength() > 0 && event;keyCode === 13) { creatListElement(). } } button,addEventListener("click"; addListAfterClick). input,addEventListener("keypress"; addListAfterKeypress);
 li { color: black; } h1, p { color: black; } button { color: white; background: #1C3144; padding: 10px; border-radius: 3px; border-style: none; } input { border-radius: 3px; padding: 10px; }.testingIt { text-decoration-line: line-through; }.deleteButton { background-color: #A31420; color: #fff; border-radius: 3px; margin: 20px; border-style: none; }.done { text-decoration: line-through #A31420; }
 <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>Notebook</li> <li>Jello</li> <li>Spinach</li> <li>Rice</li> <li>Birthday cake</li> <li>Candles</li> </ul> </body>

That because you only listen click event for only dymanic added li element.那是因为你只监听动态添加的li元素的click事件。

You should add event listenner for hard-code elements also.您还应该为硬编码元素添加事件侦听器。 In example below I show a alert when click to li item在下面的示例中,我在点击li项目时显示警报

document.querySelectorAll('li').forEach(liItem => {
  liItem.addEventListener("click", function() {
    alert('click');
  });
})

https://codepen.io/1412108/pen/OJbgJEW?editors=1010 https://codepen.io/1412108/pen/OJbgJEW?editors=1010

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM