необходимость дважды нажать клавишу для EventListener (javascript)


Я делаю некоторые манипуляции DOM в javascript (я знаю, что есть и другие более быстрые способы, я просто пытаюсь сначала изучить старые способы!)

Я создал этот EventListener:

document.addEventListener("keydown", delitem);

..и следующая функция:

function delitem(evt) {
if (evt.keyCode == 46) {
ul.removeChild(ul.lastChild);
  }
}

Надеюсь, что когда я нажму клавишу "удалить" в любом месте на веб-странице, последний пункт в списке будет удален. Тем не менее, я должен нажать клавишу "delete" дважды, чтобы он работал, и я понятия не имею, почему это происходит?

Если я добавлю новый элемент в список, то я могу нажать "Удалить" один раз, чтобы удалить его.. но для существующих элементов он должен быть нажат дважды. Ценю вашу помощь.

Вот HTML:

<ul class="list-group "> 
<li class="list-group-item list-group-item-info ">Notebook</li>
<li class="list-group-item list-group-item-info ">Peas</li>
<li class="list-group-item list-group-item-info ">Spinach</li>
<li class="list-group-item list-group-item-info ">Rice</li>
<li class="list-group-item list-group-item-info ">Birthday Cake</li>
<li class="list-group-item list-group-item-info ">Candles</li>
</ul>
3 4

3 ответа:

lastChild возвращает последний узел внутри элемента, и этот узел является textnode, поскольку вы получили новую строку в конце строки, которая интерпретируется как текст:

 </li>\n</ul>

Поскольку вы хотите получить последний элемент, а не последний узел, вы можете использовать lastElementChild вместо этого или просто удалить разрыв строки:

 </li></ul>

Вот полный код, он должен работать

<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<ul class="list-group "> 
<li class="list-group-item list-group-item-info ">Notebook</li>
<li class="list-group-item list-group-item-info ">Peas</li>
<li class="list-group-item list-group-item-info ">Spinach</li>
<li class="list-group-item list-group-item-info ">Rice</li>
<li class="list-group-item list-group-item-info ">Birthday Cake</li>
<li class="list-group-item list-group-item-info ">Candles</li>
</ul>
<script>
document.addEventListener("keydown", delitem);
var ul = document.querySelector('ul');
function delitem(evt) {
if (evt.keyCode == 46 && ul.children.length ) {
ul.removeChild(ul.lastChild);
  }
}
</script>
</body>
</html>

Вы можете использовать lastElementChild или запросить последний элемент.

Https://codepen.io/anon/pen/WKPgjg

window.addEventListener('load', () => {
  const ul = document.querySelector('.list-group');

  document.addEventListener('keydown', (ev) => {
    if (ev.keyCode === 8) {
      // query for the last li element to avoid text nodes
      const lastChild = ul.querySelector(':last-child');

      if (lastChild) {
        ul.removeChild(lastChild);        
      }

      // alternatively you could use this
      //https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/lastElementChild
      // ul.removeChild(ul.lastElementChild);
    }
  });
});