Почему элемент игнорируется?

var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(event){
  var target = event.target;
  if(target.tagName === 'LI'){
    if(event.ctrlKey || event.metaKey){
      target.classList.toggle('selected');
    } else if(event.shiftKey){

    } else {
      var selected = ul.getElementsByClassName('selected');
      for(var i = 0; i < selected.length; i++){
        selected[i].classList.remove('selected');
      }
    }
  }
}

<ul>
    <li>Кристофер Робин</li>
    <li>Винни-Пух</li>
    <li>Ослик Иа</li>
    <li>Мудрая Сова</li>
    <li>Кролик. Просто кролик.</li>
  </ul>

Как исправить эту проблемы? Игнорируются элементы, а нужно, чтобы у каждого элемента, у которого уже есть класс selected, он пропадал.

1:

b752236b5b6d40ca9db76057067cf53a.png
2:

1ab9210bd62f4db8b9bedcb299c214ac.png
  • Вопрос задан
  • 128 просмотров
Решения вопроса 1
bingo347
@bingo347 Куратор тега JavaScript
Crazy on performance...
getElementsByClassName возвращает nodeList, который обновляется при изменениях в dom
Допустим у Вас выделено 3 элемента, их индексы в nodeList 0, 1 и 2
Вы перебираете их циклом for(var i = 0; i < selected.length; i++)
На первой итерации цикла Вы убираете класс у 0 элемента, при этом он так же исчезает из nodeList, который сформирован по этому классу, 1й элемент становится нулевым, 2й - первым, length становится 2
На второй итерации Вы убираете класс у элемента с индексом 1, который изначально был 2, nodeList опять обновляется
Третьей итерации уже не происходит, так как i == 2, а selected.length == 1, цикл завершается.
Оптимальнее, как в плане производительности, так и в плане правильной логики перебирать nodeList d обратном порядке, так элемент будет удаляться с конца nodeList - что быстрее, а у необработанных элементов останутся прежние индексы
for(var i = selected.length; i--; ){
        selected[i].classList.remove('selected');
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы