从父元素中删除子项成功但引发了错误

时间:2017-05-19 08:40:16

标签: javascript html parent-child

考虑我做的这个例子,其特点是将每个输入的输入文本转换为标签。

示例代码



 
    var query = document.querySelector.bind(document);
    
    query('#textfield').addEventListener('keyup', addTag);
    
    function addTag(e) {
      var evt = e.target;
    
      if(evt.value) {
        var items = evt.value.split(',');
    
        if(items.length <= 10) {
          evt.nextElementSibling.innerHTML = null;
    
          for(var i = 0; i < items.length; i++) {
            if(items[i].length > 0) {
              var label = document.createElement('label'),
                  span = document.createElement('span');
              
              label.className = 'tag';
              label.textContent = items[i];
    
              span.className = 'remove';
              span.title = 'Remove';
              span.textContent = 'x';
    
              label.insertAdjacentElement('beforeend', span);
    
              evt.nextElementSibling.appendChild(label);
    
              for(var l = 0; l < evt.nextElementSibling.children.length; l++) {
                evt.nextElementSibling.children[l].firstElementChild.addEventListener('click', function() {
                  var $currentElement = this;
    
                  $currentElement.parentNode.parentNode.removeChild($currentElement.parentNode);
                })
              }
            }
          }
        }
      } else {
        evt.nextElementSibling.innerHTML = null;
      }
    }
&#13;
    section {
      width: 100%;
      height: 100vh;
    
      background: orange;
    
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .container {
      width: 50%;
    }
    
    input[name] {
      width: 100%;
      border: none;
      border-radius: 1rem 1rem 0 0;
      font: 1rem 'Arial', sans-serif;
      padding: 1rem;
      background: #272727;
      color: orange;
      box-shadow: inset 0 0 5px 0 orange;
    }
    
    input[name]::placeholder {
      font: 0.9rem 'Arial', sans-serif;
      opacity: 0.9;
    }
    
    .tags {
      width: 100%;
      height: 250px;
      padding: 1rem;
      background: #dfdfdf;
      border-radius: 0 0 1rem 1rem;
      box-shadow: 0 5px 25px 0px rgba(0,0,0,0.4);
      position: relative;
    }
    
    .tags > label {
      width: auto;
      display: inline-block;
      background: #272727;
      color: orange;
      font: 1.1rem 'Arial', sans-serif;
      padding: 0.4rem 0.6rem;
      border-radius: .2rem;
      margin: 5px;
    }
    
    .tags > label > span {
      font-size: 0.7rem;
      margin-left: 10px;
      position: relative;
      bottom: 2px;
      color: #ff4d4d;
      cursor: pointer;
    }
&#13;
 <section id="tags-input">
      <div class="container">
        <input type="text" name="items" id="textfield" placeholder="Enter any item, separated by comma(','). Maximum of 10" autofocus>
        <div class="tags"></div>
      </div>
    </section>
&#13;
&#13;
&#13;

它很成功但是当我在删除标签的同时打开控制台时,我注意到它删除了我删除的每个标记上的错误:

  

未捕获的TypeError:无法读取属性&#39; removeChild&#39;为null

为什么会这样?我相信使用parentNode两次并没有错。是因为我在事件监听器中有另一个事件监听器吗?因为如果我在外面创建另一个事件监听器,由于关闭按钮位于每个标签内部,因此无法通过添加和删除标签进行实时更新

1 个答案:

答案 0 :(得分:1)

这是因为您将点击事件添加到“span.remove&#39;超过1次。尽量不要将该事件添加到所有&#39; span.remove&#39;每次。