在JavaScript中向<ul>元素添加/删除<li>元素

4
我是JavaScript的新手,正在学习各种东西。现在我卡在了从列表中添加和删除li元素上。使用jQuery的练习我做得很好,但是现在我在用纯JS版本时遇到了困难。
主要思路是通过点击按钮添加一个新的li元素,并通过点击旁边的X按钮删除该元素。我尝试使用“this”和其他在Stackoverflow类似问题中提到的建议,但对我来说都没有起作用。您能否指导我做错了什么?
P.S.添加功能似乎在片段中可以工作,但控制台记录错误:无法读取null的“addeventlistener”属性。

//declaring the variables
var btn = document.getElementsByClassName('btn');
var list = document.getElementById('list');
var add = document.getElementById('add');

//adding a new element to the list
add.addEventListener('click', function(){
  var newElement = document.createElement('LI');
  list.appendChild(newElement);
  newElement.innerHTML= "I am a new element<button class='btn'>X</button>";
});

//removing the clicked element
btn.addEventListener('click', function(){
  list.parentNode.removeChild(this);
});
ul li {
  decoration: none;
  display: block;
  margin-top: 1em;
  text-align: center;
  font-family:  'Avant Garde', Avantgarde, 'Century Gothic', CenturyGothic, AppleGothic, sans-serif;
  font-size: 18px;
}

#add {
  background-color: black;
  color: white;
  border: none;
  width: 280px;
  font-color: white;
  border-radius: 8px;
  font-size: 16px;
  padding: 15px;
  outline: none;
  text-align: center;
  margin: 20px auto;
  display: block;
}

#add:hover {
  background-color: #28364d;
  color: white;
  border: none;
  outline: none;
}

#add:active {
  position: relative;
  bottom: 2px;
}

.btn{
  margin-left: 10px;
  border-radius: 10px;
  background-color: #000;
  color: white;
  border: none;
  outline: none;
  font-size: 14px;
  font-family: sans-serif;
}

.btn:active {
position: relative;
bottom: 2px;
}
<div>
      <ul id="list">
        <li class="element">I am a new element<button class="btn">X</button></li>
        <li class="element">I am a new element<button class="btn">X</button></li>
        <li class="element">I am a new element<button class="btn">X</button></li>
        <li class="element">I am a new element<button class="btn">X</button></li>
        <li class="element">I am a new element<button class="btn">X</button></li>
      </ul>

    <button id="add">Add an element to the list</button>
</div>


1
为了解决您当前的问题以及未来使用新元素时可能遇到的问题,请查看名为“事件委托”的内容 https://davidwalsh.name/event-delegate - rlemon
谢谢,我一定会的! - Ani
3个回答

2
在您的情况下,btn 是一个元素节点列表,而不是一个元素,因此您无法将事件附加到数组上。您需要遍历它们:
for(i=0; i < btn.length; i++) {
   btn[i].addEventListener('click', function(){
      list.parentNode.removeChild(this);
   });
}

1
虽然目前看起来是正确的,但从长远来看并不可行。他正在动态地添加元素。 - rlemon
那是另一个任务,我可以改进答案,但OP正在询问“无法读取空值的'addeventlistener'属性”。你在动态元素方面是正确的。 - Marcos Pérez Gude

2

这将返回一个非动态集合:

var btn = document.getElementsByClassName('btn');

这意味着它只包含在方法调用时存在的对象。您需要在创建新的li元素之后调用getElementsByClassName(),并在每个按钮上附加EventListeners。只需记住不要在按钮上重复放置EventListener。
更好的解决方案是:不要使用getElementsByClassName(),而是直接在函数中附加事件处理程序,在其中创建新按钮。这样,您就不必担心预先存在的事件处理程序了。
add.addEventListener('click', function(){
    var newElement = document.createElement('LI');
    list.appendChild(newElement);
    newElement.innerHTML= "I am a new element<button class='btn'>X</button>";
    newElement.addEventListener('click', function () {
        this.parentNode.removeChild(this);
    });
});

1
我也在学习中,作为新手来说,这是一个不错的小挑战。感谢rlemon提供的文章链接,让我们找到了正确的方向。我在这里学到了一些东西。
如果你对我得出的结果感兴趣: https://jsfiddle.net/nyxhj0tg/1/ JS:
var list = document.getElementById('list');
var add = document.getElementById('add');

//adding a new element to the list
add.addEventListener('click', function(){
  var newElement = document.createElement('LI');
  list.appendChild(newElement);
  newElement.innerHTML= "I am a new element<button class='btn'>X</button>";

});

list.addEventListener('click', function(e){
  if(e.target && e.target.nodeName == "BUTTON") {
        console.log("Button ", e, " was clicked!");
    e.target.parentNode.remove();
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接