如何使用 JavaScript 修复 "toggle" a "classList"

How to fix "toggle" a "classList" using JavaScript

我有一个要添加的列表 class,但只有通过输入添加后的项目才能使用切换。代码中的项目不起作用。

我想知道是否也与“这个”有关属性。

Link 到 CodePen。

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();
    }
})

那是因为您只监听 click 动态添加的 li 元素的事件。

您还应该为硬编码元素添加事件侦听器。在下面的示例中,当单击 li

时,我会显示警报
document.querySelectorAll('li').forEach(liItem => {
  liItem.addEventListener("click", function() {
    alert('click');
  });
})

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

如果查看您编写的代码,您只是将事件处理程序附加到新创建的 li 节点。 要绕过它,您可以在页面加载时将事件处理程序附加到所有现有的 li 元素,或者您可以使用 event delegation 的概念绑定事件处理程序一次。我发现第二种方法更简洁,因为您不必担心在将新的 li 元素添加到 DOM.

后添加处理程序

我在您的代码中发现了以下问题。

  • 没有将点击处理程序附加到现有 li 元素。
  • 在删除 libutton 时不删除它们的点击处理程序(这可能会导致应用程序内存泄漏)。

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>