使用removeChild和addEventListener进行Javascript DOM操作错误

问题描述 投票:-1回答:3

我基本上建立了一个非常简单的列表。在顶部的输入字段中写入内容,单击按钮,它将显示在下方的ul中。

我在我的控制台中遇到两个错误,我不确定我做错了什么。

首先,在第12行,这个事件监听器:

deleteBtn.addEventListener('click', removeItem);

错误显示“无法读取属性'addEventListener'为null”并且我认为这是因为deleteBtn不在加载页面上,当您向列表添加项目时,它将添加到带有li的DOM中。

其次,在第40行:

selectedItem.removeChild(checkMark);

错误显示“无法在'节点'上执行'removeChild':要删除的节点不是此节点的子节点。”

这是我的所有代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Bootstrap Crash Course</title>

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"
        integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb"
        crossorigin="anonymous" />
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
        crossorigin="anonymous">

  <style type="text/css">
    #myButton {
      cursor: pointer;
    }

    .input-group {
      margin: 15px 0;
    }

    .fa-times-circle-o {
      font-size: 24px;
      cursor: pointer;
    }

    .fa-check-circle {
      font-size: 24px;
    }

  </style>
</head>
<body>

<div class="container">

  <div class="input-group">
    <input type="text" class="rounded form-control" id="myInput" />
    <span id="myButton" class="input-group-addon">Click</span>
  </div>

  <ul class="list-group" id="myOutput">

  </ul>

</div> <!-- .containter -->




  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
          integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
          crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"
          integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh"
          crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"
          integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ"
          crossorigin="anonymous"></script>
  <script src="app.js"></script>
</body>
</html>

//Code from app.js

let myButton = document.getElementById('myButton');
let myOutput = document.getElementById('myOutput');
let myInput = document.getElementById('myInput');
let listGroupItems = document.querySelectorAll('.list-group-item');
let deleteBtn = document.getElementById('deleteBtn');

setUpEventListeners();

function setUpEventListeners() {
  myButton.addEventListener('click', addItem);
  myOutput.addEventListener('click', toggleItem);
  deleteBtn.addEventListener('click', removeItem);
}

function addItem() {
  if (myInput.value === '') {
    console.log('Field is empty!');
  } else {
    let li = document.createElement('li');
    let inputValue = document.createTextNode(myInput.value);

    li.innerHTML = '<i class="fa fa-times-circle-o float-right" aria-hidden="true" id="deleteBtn"></i>';
    li.className = 'list-group-item';
    myOutput.appendChild(li);
    li.appendChild(inputValue);
  }
  myInput.value = '';
}

function toggleItem(e) {
  let selectedItem = e.target;
  let checkMark = document.createElement('i');
  checkMark.classList.add('fa', 'fa-check-circle', 'float-left');

  console.log(selectedItem);

  if (selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
    selectedItem.classList.remove('bg-success');
    selectedItem.classList.remove('text-white');
    //listGroupItems.removeChild(checkMark);
  } else if (!selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
    selectedItem.classList.add('bg-success');
    selectedItem.classList.add('text-white');
    selectedItem.appendChild(checkMark);
  }
}

function removeItem() {
  e.target.parentElement.remove();
}
javascript dom addeventlistener removechild
3个回答
0
投票

不是在创建之前向deleteBtn添加事件,而是在创建按钮时使用onclick添加内联事件并调用函数removeItem并使用this传递上下文

对于第二个问题,listGroupItems是一个数组。所以数组中没有removeChild方法。

要解决第二个问题,请从childNodes集合中获取图标的索引。然后使用该索引删除此特定子项

let myButton = document.getElementById('myButton');
let myOutput = document.getElementById('myOutput');
let myInput = document.getElementById('myInput');
let listGroupItems = document.querySelectorAll('.list-group-item');


setUpEventListeners();

function setUpEventListeners() {
  myButton.addEventListener('click', addItem);
  myOutput.addEventListener('click', toggleItem);

}

function addItem() {
  if (myInput.value === '') {
    console.log('Field is empty!');
  } else {
    let li = document.createElement('li');
    let inputValue = document.createTextNode(myInput.value);
    // Changed here adding onclick
    li.innerHTML = '<i class="fa fa-times-circle-o float-right" aria-hidden="true" onclick="removeItem(this)" class="deleteBtn"></i>';
    li.className = 'list-group-item';
    myOutput.appendChild(li);
    li.appendChild(inputValue);

  }
  myInput.value = '';
}

function toggleItem(e) {
  let selectedItem = e.target;
  if (selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
    selectedItem.classList.remove('bg-success');
    selectedItem.classList.remove('text-white');
    var iconIndex = '';
    // getting the index of the icon which have the specifc class from childNodes using its class
    for (var i = 0; i < selectedItem.childNodes.length; i++) {
      if (selectedItem.childNodes[i].className === "fa fa-check-circle float-left") {
        iconIndex = i;
      }
    }
    // Using that index to remove the icon child
    selectedItem.removeChild(selectedItem.childNodes[iconIndex]);
  } else if (!selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
    let checkMark = document.createElement('i');
    checkMark.classList.add('fa', 'fa-check-circle', 'float-left');
    selectedItem.classList.add('bg-success');
    selectedItem.classList.add('text-white');
    selectedItem.appendChild(checkMark);
  }
}

function removeItem(elem) {
  elem.parentNode.remove();
}
#myButton {
  cursor: pointer;
}

.input-group {
  margin: 15px 0;
}

.fa-times-circle-o {
  font-size: 24px;
  cursor: pointer;
}

.fa-check-circle {
  font-size: 24px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

<div class="container">

  <div class="input-group">
    <input type="text" class="rounded form-control" id="myInput" />
    <span id="myButton" class="input-group-addon">Click</span>
  </div>

  <ul class="list-group" id="myOutput">

  </ul>

</div>

0
投票

deleteBtn变量是未定义的,因为您在页面加载时没有至少一个id为deleteBtn的项目。


0
投票

要使用removeChild()方法删除元素,签名是:

parentOfTarget.removeChild(target)

在下面的演示中,Template LiteralsinsertAdjacentHTML()用于合并元素创建和插入DOM。顺便说一下,你不能为多次创建的元素分配一个id。 ids是独特的,所以#deleteBtn被删除。如果你还是delegate events,按钮上不需要id。

有大量的课程上下班,所以我把它们放在数组中,然后在forEach()的每次迭代中切换每个类

详情在演示中评论

演示

var xBtn = document.getElementById('xButton');
var xOut = document.getElementById('xOutput');
var xInp = document.getElementById('xInput');

xBtn.addEventListener('click', addItem);
xOut.addEventListener('click', iconClick);

function addItem() {
  if (xInp.value === '') {
    console.log('Field is empty!');
  } else {
    /* This is a Template Literal which is a string
    || with powerful syntax and methods
    */
    let li = `<li class='list-group-item'>
    <i class="fa fa-circle-o float-left"></i>
    &nbsp;${xInp.value}&nbsp;
    <i class="fa fa-times-circle-o float-right"></i>
    </li>`;

    // Use insertAdjacentHTML() instead of innerHTML
    xOut.insertAdjacentHTML('beforeend', li);
  }
  xInp.value = '';
}

function iconClick(e) {

  // Reference e.target
  var tgt = e.target;
  // Reference e.target's parent
  var item = tgt.parentElement;

  /* if e.target has class .float-left
  || forEach() will...
  */
  if (tgt.classList.contains('float-left')) {

    // toggle e.target's FA icon classes
    ['fa-check-circle', 'fa-circle-o'].forEach(function(c, idx) {
      tgt.classList.toggle(c);
    });

    // toggle e.target's parent's state classes
    ['bg-success', 'text-white'].forEach(function(i, idx) {
      item.classList.toggle(i);
    });

    /* ...but if it has class .float-right
    || remove the parent of e.target by referencing
    || the parent of the parent of e.target (grandma)
    */
  } else if (tgt.classList.contains('float-right')) {
    xOut.removeChild(item);

    // ...otherwise just end function
  } else {
    return false;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Bootstrap Crash Course</title>

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
  <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

  <style>
    #xButton {
      cursor: pointer;
    }
    
    .input-group {
      margin: 15px 0;
    }
    
    .fa {
      font-size: 24px;
      cursor: pointer;
    }
  </style>
</head>

<body>

  <div class="container">

    <div class="input-group">
      <input type="text" class="rounded form-control" id="xInput" />
      <button id="xButton" class="btn btn-primary input-group-addon">ADD</button>
    </div>

    <ul class="list-group" id="xOutput">

    </ul>

  </div>
  <!-- .containter -->




  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>

</body>

</html>
© www.soinside.com 2019 - 2024. All rights reserved.