Простой js forl oop только итерации - PullRequest
2 голосов
/ 10 февраля 2020

У меня есть JS для l oop, который перебирает все элементы с указанным классом c, а затем удаляет класс. Однако, пока l oop работает для первого найденного элемента, он останавливается. Я не вижу никаких ошибок, я попробовал это в try / catch и не вижу ничего другого, что могло бы вызвать проблему. У кого-нибудь есть предложения? Спасибо:)

let visibleTags = document.getElementsByClassName('show');
console.log(visibleTags.length) // length is 2

for (let index = 0; index < visibleTags.length; index++) {
   console.log(index); // 0
   visibleTags[index].classList.remove('show'); // removes 'show' from element 0
}

// element 1 still has the 'show' class and was not touched by the loop... ?

Ответы [ 5 ]

1 голос
/ 10 февраля 2020

Не следует использовать индексы, visibleTag - это живая коллекция, и вы изменяете часть критериев выбора (класс show), чтобы сама коллекция изменилась. Поскольку вы хотите удалить show из всего, что имеет класс show, лучше использовать while l oop:

let shown = document.getElementsByClassName('show');
while(shown.length > 0) {
  shown[0].classList.remove('show');
}
<div>
  <div class="show">1</div>
  <div class="show">2</div>
  <div class="show">3</div>
  <div class="show">4</div>
</div>
1 голос
/ 10 февраля 2020

visibleTags - это «живой» запрос DOM - элементы в нем будут меняться при изменении DOM.

Поэтому, когда вы удаляете класс show из элемента, он одновременно исчезает из visibleTags, так как ваш запрос был для элементов с классом show. Таким образом, как только вы удалите класс, visibleTags.length упадет до 1, и ваш l oop выйдет, потому что счетчик l oop уже равен 1.

Есть несколько способов чтобы работать с этим:

  • Одним из решений этого является запуск l oop в обратном направлении, чтобы он начинался с visibleTags.length и возвращался к нулю. Таким образом, вы можете удалить элементы, и длина уменьшится, но затем вы перейдете к предыдущему, и l oop продолжит.

  • Другой вариант - запустить l oop как while l oop и просто продолжайте удалять первый элемент: ie:

    while (visibleTags.length) {
        visibleTags[0].classList.remove('show');
    }
    

    Это было бы моим предпочтительным решением.

  • Наконец, вы можете создать ненасыщенный массив элементов, через которые вы можете l oop пройти. Вероятно, вам не нужно этого делать, но это может быть полезным вариантом, если позже вам потребуется снова выполнить l oop через тот же список элементов (например, возможно, для восстановления класса show).

0 голосов
/ 10 февраля 2020

Вы можете использовать querySelectorAll, чтобы выбрать все элементы с классом show.

Метод Document querySelectorAll () возвращает stati c (не в реальном времени) NodeList, представляющий список элементы документа, которые соответствуют указанной группе селекторов. Подробнее об этом селекторе здесь

function removeClass() {
    let visibleTags = document.querySelectorAll(".show");
    console.log("Number of selected Elements: ", visibleTags.length); // length is 2

    for (let index = 0; index < visibleTags.length; index++) {
         console.log("Index: ", index); // 0
         visibleTags[index].classList.remove("show"); // removes 'show' from element 0
    }
}
.show {
 background-color: red;
}
  <button onclick="removeClass()">Remove Class</button>
  <br/>
   <br/>
  <div>
      <div class="show test">1</div>
      <div class="show test">2</div>
    </div>
0 голосов
/ 10 февраля 2020

Попробуйте использовать эту функцию:

function removeClassFromElements(className) {
  document
    .querySelectorAll(`.${className}`)
    .forEach(el => el.classList.remove(className));
}

Для вашего случая:

removeClassFromElements('show');
0 голосов
/ 10 февраля 2020

Это потому, что document.getElementsByClassName() ссылается на массив фактических элементов, соответствующих вашему классу.

Таким образом, при итерации и изменении своего класса сам элемент больше не принадлежит массиву таким образом, индекс становится index-1.

Обходной путь, если у вас нет другого пути для достижения объекта, - это полагаться на другой класс / селектор для получения списка элементов:

let visibleTags = document.getElementsByClassName('test');
console.log(visibleTags.length) // length is 2

for (let index = 0; index < visibleTags.length; index++) {
   console.log(index); // 0
   visibleTags[index].classList.remove('show'); // removes 'show' from element 0
}
.test { 
  width: 300px;
  height: 300px;
  border: 1px solid #ccc;
}

.show {
  background-color: red;
}
<div>
  <div class="show test">1</div>
  <div class="show test">2</div>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...