item.addEventListener запускается автоматически

#javascript #dom-events

#javascript #dom-события

Вопрос:

Я изучаю JS, следуя урокам Уэса Боса. Я пытаюсь выбирать кнопки и отображать информацию каждый раз, когда пользователь нажимает на них. Поэтому я добавляю прослушиватель событий, однако резервная функция, похоже, выполняется автоматически, когда она находится внутри прослушивателя событий. Я не понимаю, почему «привет» отображается автоматически, в то время как функция youClickTheButton выполняется только тогда, когда пользователь нажимает на кнопку (см. Приведенный Ниже Код).

Почему это происходит?

 const myButtons = document.querySelectorAll('.cards button');
const modalOuter = document.querySelector('.modal-outer');

function youClickTheButton(event) {
  console.log(event);
  modalOuter.classList.add('open');
}

myButtons.forEach(item => item.addEventListener('click', youClickTheButton));
myButtons.forEach(item => item.addEventListener('click', console.log('hello')));
  

 // whenever you click on the button it will open a pop up with a picture with the description
// whenever you click outside of this pop up it should close itself use .closest()

// populate the modal with name and description of the card so you don't have to modify the .html file

// you could also close it by simply pressing escape

const myButtons = document.querySelectorAll('.cards button');
const modalOuter = document.querySelector('.modal-outer');

function youClickTheButton(event) {
  console.log(event);
  modalOuter.classList.add('open');
}

myButtons.forEach(item => item.addEventListener('click', youClickTheButton));
myButtons.forEach(item => item.addEventListener('click', console.log('hello')));  
 <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title></title>
  <link rel="stylesheet" href="../../base.css">
</head>

<body>
  <div class="cards">
    <div class="card number1" data-description="Wes is cool">
      <img src="https://picsum.photos/200?random=1" alt="Wes Bos">
      <h2>Wes Bos</h2>
      <button>Learn more →</button>
    </div>
    <div class="card number2" data-description="Scott is neat!">
      <img src="https://picsum.photos/200?random=2" alt="Wes Bos">
      <h2>Scott Tolinski</h2>
      <button>Learn more →</button>
    </div>
    <div class="card number3" data-description="Kait is beautiful!">
      <img src="https://picsum.photos/200?random=3" alt="Wes Bos">
      <h2>Kait Bos</h2>
      <button>Learn more →</button>
    </div>
    <div class="card number4" data-description="Snickers is a dog!">
      <img src="https://picsum.photos/200?random=4" alt="Wes Bos">
      <h2>Snickers the dog</h2>
      <button>Learn more →</button>
    </div>

  </div>

  <div class="modal-outer ">
    <div class="modal-inner ">
      <p>You clicked on the 1st one</p>
    </div>
  </div>



  <style>
    .cards {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      grid-gap: 20px;
      padding: 2rem;
    }

    .card {
      background: white;
      padding: 1rem;
      border-radius: 2px;
    }

    .card img {
      width: 100%;
    }

    .card h2 {
      color: black;
    }

    .modal-outer {
      display: grid;
      background: hsla(50, 100%, 50%, 0.7);
      position: fixed;
      height: 100vh;
      width: 100vw;
      top: 0;
      left: 0;
      justify-content: center;
      align-items: center;
      /* Hide this modal until we need it */
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.2s;
    }

    .modal-outer img {
      width: 100%;
    }

    .modal-outer.open {
      opacity: 1;
      pointer-events: all;
    }

    .modal-inner {
      max-width: 600px;
      min-width: 400px;
      padding: 2rem;
      border-radius: 5px;
      min-height: 200px;
      background: white;
      transform: translateY(-200%);
      transition: transform 2s;
    }

    .modal-outer.open .modal-inner {
      transform: translateY(0);
    }
  </style>
  <script src="./click-outside_5.js"></script>
</body>

</html>  

Ответ №1:

Проверьте разницу между вашими двумя item.addEventListener() . В первом случае вы передаете функцию, а во втором вызываете ее (без скобок или скобок).

Если вы передаете функцию обратного вызова (т. Е. Первый случай), Вы не вызываете ее немедленно, вы просто говорите, что «Вот эта функция, которую я создал, запускайте ее каждый раз, когда кто-то нажимает на любую из этих кнопок».

Если вы хотите войти из своей второй функции, вам нужно передать функцию, а не результат функции:

 myButtons.forEach(item => item.addEventListener('click', () => console.log('hello')))

// OR

function logHello() {
  return console.log('hello')
} 

myButtons.forEach(item => item.addEventListener('click', logHello));
  

Подробнее об этом можно прочитать в MDN.

В любом случае, вам не следует дважды перебирать кнопки, но я думаю, что в данный момент вы просто тестируете вещи. console.log('hello') может быть в вашей youClickTheButton() функции.