Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Как повесить событие сразу на несколько одинаковых элементов? (https://javascript.ru/forum/events/80527-kak-povesit-sobytie-srazu-na-neskolko-odinakovykh-ehlementov.html)

vlad_kl 16.06.2020 21:40

Как повесить событие сразу на несколько одинаковых элементов?
 
Доброго времени суток.

Подскажите, пжлста. Как повесить событие сразу на несколько одинаковых элементов?
Например. У меня есть 5 спанов. Я хочу повесить событие: при наведении на каждый спан в отдельности - чтоб менялся бэкграунд.

Попытался сделать querySelectorAll - но понял, что событие на полученный массив спанов не вешается. Получается только повесить событие на 1-й спан, как в примере ниже.
Какие есть варианты решения проблемы?

<body>
    <div>
        <span class="span">#1</span>
        <span class="span">#2</span>
        <span class="span">#3</span>
        <span class="span">#4</span>
        <span class="span">#5</span>
    </div>
</body>



let spans = document.querySelector('.span');
let changeColor = () => spans.classList.toggle('redbackground');
spans.addEventListener('mouseover', changeColor);


Я заранее прошу прощения, если мой вопрос покажется вам тупым, я новичок в js, только обучаюсь этому. Но потратил 3-4 часа на гугление и самостоятельный подбор разных вариантов и ничего не придумал и не нашёл.
Спасибо

рони 16.06.2020 22:11

vlad_kl,
https://learn.javascript.ru/event-delegation

Error 16.06.2020 22:16

Можно использовать циклы, а можно делегирование событий:
<head>
 <style>
  span{
   display:inline-block;
   padding:1em;
}
 </style>
</head>
<body>
  <div id="spans">
    <span class="span">#1</span>
    <span class="span">#2</span>
    <span class="span">#3</span>
    <span class="span">#4</span>
    <span class="span">#5</span>
  </div>
  <div id="spans2">
    <span class="span">#a</span>
    <span class="span">#b</span>
    <span class="span">#c</span>
    <span class="span">#d</span>
    <span class="span">#e</span>
  </div>
  <script>
   document.getElementById('spans').addEventListener('click', (event)=>{
      const t = event.target.closest('span');
      if(t){event.target.style.backgroundColor="purple"}
    });
    for (let span of document.querySelectorAll('#spans2 span')) {
      span.onclick = () => {
        span.style.backgroundColor = "gold"
      }
    }
  </script>
</body>

рони 16.06.2020 22:29

делегирование и handleEvent
 
vlad_kl,
https://learn.javascript.ru/event-delegation
https://learn.javascript.ru/introduc...ik-handleevent
<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
<style type="text/css">
.span.redbackground{
    background-color: hsla(0, 100%, 50%, 1);
}

</style>
</head>
<body>
    <div>
        <span class="span">#1</span>
        <span class="span">#2</span>
        <span class="span">#3</span>
        <span class="span">#4</span>
        <span class="span">#5</span>
    </div>
<script>
let div = document.querySelector('div');
let changeColor = {
handleEvent(event) {
const target = event.target.closest('.span');
if (!target) return;
target.classList.toggle('redbackground', event.type == 'mouseenter')
}};
div.addEventListener('mouseenter', changeColor, true);
div.addEventListener('mouseleave', changeColor, true);
</script>
</body>

</html>

vlad_kl 17.06.2020 19:03

Всем огромное спасибо за помощь. До делегирования событий в этом учебнике ещё не дошёл. А hadnle event как-то туго зашло. Пошёл учить мат часть :write:

vlad_kl 18.06.2020 22:25

Дополню.
Нужно было повесить событие на родительский div.
И чуток преобразовать код, добавив event.target.
Ну и условие closest('span'), чтоб при наведении на сам div, он не красился в красный.
Получилось идеально :)
Ещё раз спасибо за советы.

let spans = document.querySelector('#span');
spans.addEventListener('mouseover', changeColor);
function changeColor (event) {
    let span = event.target.closest('span');
    if (!span) return;
    span.classList.toggle('redbackground');
}


Часовой пояс GMT +3, время: 07:30.