JS код работает только у первого элемента списка?

Рейтинг: 0Ответов: 2Опубликовано: 18.01.2023

Почему js работает только в первом элементе списка?

const play = document.querySelector('.podcast-cart__content-btn-play');
const pause = document.querySelector('.podcast-cart__content-btn-pause');

function clickPlay() {
  play.style.color = '0';
  play.style.visibility = 'hidden';
  pause.style.opacity = '1';
  pause.style.visibility = 'visible';
  pause.style.transform = 'scale(1.1)';
};

function clickPause() {
  pause.style.opacity = '0';
  pause.style.visibility = 'hidden';
  play.style.opacity = '1';
  play.style.visibility = 'visible';
};

play.addEventListener('click', clickPlay);
pause.addEventListener('click', clickPause);

// for (var i = 0; i < play.length; i++) {
//   play[i].addEventListener("click", function () {
//     play.style.opacity = '0';
//     play.style.visibility = 'hidden';
//     pause.style.opacity = '1';
//     pause.style.visibility = 'visible';
//     pause.style.transform = 'scale(1.1)';
//   });
// };
.podcast-cart {
  display: inline-block;
  border: 1px solid red;
}

.podcast-cart__content-btn-play {
  width: 42px;
  max-width: 100%;
  height: 41px;
  max-height: 100%;
  background-color: blue;
  border-radius: 50px;
  cursor: pointer;
  transform: scale(1);
  transition: all 0.2s linear;
}

.podcast-cart__content-btn-pause {
  width: 42px;
  max-width: 100%;
  height: 41px;
  max-height: 100%;
  background-color: green;
  border-radius: 50px;
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transition: all 0.2s linear;
}
<article class="podcast-cart">
  <div class="podcast-cart__content-btn-play  podcast-cart__content-btn" role="button" aria-label="Плэй">
  </div>

  <div class="podcast-cart__content-btn-pause  podcast-cart__content-btn" role="button" aria-label="Пауза">
  </div>
</article>

<article class="podcast-cart">
  <div class="podcast-cart__content-btn-play  podcast-cart__content-btn" role="button" aria-label="Плэй">
  </div>

  <div class="podcast-cart__content-btn-pause  podcast-cart__content-btn" role="button" aria-label="Пауза">
  </div>
</article>

<article class="podcast-cart">
  <div class="podcast-cart__content-btn-play  podcast-cart__content-btn" role="button" aria-label="Плэй">
  </div>

  <div class="podcast-cart__content-btn-pause  podcast-cart__content-btn" role="button" aria-label="Пауза">
  </div>
</article>

https://codepen.io/Jane111/pen/poZWaRZ

Пробовал находить две кнопки через querySelectorAll. Получал ошибку, что функция не найдена.

Далее пробовал использовать цикл (в комментариях по ссылке) Но получал ошибку в строке 5.

Почему при использовании цикла, js не меняет css свойство, а выдает ошибку?

Ответы

▲ 3

Почему js работает только в первом элементе списка?

Поскольку

const play = document.querySelector('.podcast-cart__content-btn-play');

и

const pause = document.querySelector('.podcast-cart__content-btn-pause');

выбирают только первые элементы удовлетворяющие условию - вся работа ведется только с ними.

Для выбора всех элементов нужно использовать

const play = document.querySelectorAll('.podcast-cart__content-btn-play');
// и
const pause = document.querySelectorAll('.podcast-cart__content-btn-pause');

А еще лучше применить делегирование событий дабы не "размножать" обработчики событий.

▲ 2

@ksa прав, нужно использовать querySelectorAll. Ниже набросал ответ с минимумом изменений исходника, не претендую на решение, т.к. все зависит от общей задачи, т.е. для чего в дальнейшем будут использоваться переключатели, от структуры проекта и т.п.

  let play, pause;
  // группа кнопок (play+pause)
  let buttons = document.querySelectorAll('.podcast-cart');
  function clickBtn(event) {
    // определяем нужные нам play и pause
    play = event.target.parentNode.querySelector('.podcast-cart__content-btn-play');
    pause = event.target.parentNode.querySelector('.podcast-cart__content-btn-pause');
    // и куда нажали, в зависимости от этого запускаем нужную функцию
    if (event.target.classList.contains('podcast-cart__content-btn-play'))
      clickPlay();
    else
      clickPause();
  };
  function clickPlay() {
    play.style.color = '0';
    play.style.visibility = 'hidden';
    pause.style.opacity = '1';
    pause.style.visibility = 'visible';
    pause.style.transform = 'scale(1.1)';
  };

  function clickPause() {
    pause.style.opacity = '0';
    pause.style.visibility = 'hidden';
    play.style.opacity = '1';
    play.style.visibility = 'visible';
  };

buttons.forEach(el=>{el.addEventListener('click', clickBtn)});