Вызов функции JS заменен другим

#javascript

#javascript

Вопрос:

У меня странная проблема, когда одна из моих функций (removeTransition) игнорируется, а вызывается другая (addTransition). Что здесь происходит?

добавлен фрагмент для вопроса вместо внешнего codepen :

    const example = document.querySelector('#myExample');

    function addTransition () {
      example.classList.add('transition');
      console.log('addTransition',example);
    }

    function removeTransition () {
      example.classList.remove('transition');
      console.log('removeTransition',example);
    }

    const el = document.querySelector('.example');
    const output = document.querySelector('#output');

    el.addEventListener('transitionend', function() {
      output.textContent = 'Transition ended'; 
    });

    document.addEventListener('click', addTransition);  
  .example {
      width: 100px;
      height: 50px;
      background: pink;
      transition-property: transform background;
      transition-duration: 2s;
      transition-delay: 1s;
    }

    .transition {
      background: cyan;
      width: 200px;
    }

    .transition::after {
      content: 'Transition class added'
    }  
     <div id="myExample" class="example"></div>
    <br>
    <button onClick="addTransition">Add</button>
    <button onClick="removeTransition">Remove</button>
    <div id="output"></div>

   

Комментарии:

1. Ваши onclick атрибуты неверны, они должны вызывать функцию, а не просто ссылаться на функцию. (Тогда ваши document.addEventListener('click', addTransition); вызовы addTransition независимо.) Лучше всего полностью избегать встроенных обработчиков

2. О, я понимаю. Я не только забыл прослушиватель событий для removeTrasition, я обобщил его, поэтому любой щелчок по документу запускает вызов функции. Даже для самого элемента я все равно могу использовать только одно событие щелчка, поэтому вместо этого пришлось бы добавить, возможно, переключатель. Я не уверен, что это за терминология встроенного обработчика. Я погуглю это. Спасибо.

Ответ №1:

Происходят две вещи:

  1. onxyz Обработчики событий в стиле старого стиля должны вызывать функцию, а не просто ссылаться на нее. Поэтому вам нужно () будет использовать эти:

     <button onClick="addTransition">Add</button>
    <!--                          ^---- missing ()    -->
    <button onClick="removeTransition">Remove</button>
    <!--                             ^---- missing () -->
      
  2. Вы вызываете addTransition , когда есть щелчок в любом месте документа:

     document.addEventListener('click', addTransition)
      

Чтобы исправить это:

  1. Не используйте стиль атрибута даже вместо обработчиков.
  2. Подключите свои обработчики с помощью addEventListener .
  3. Попросите их остановить распространение события.
  4. Удалите обработчик, который у вас включен document (?). Я не уверен, для чего это предназначено.

Что-то вроде этого:

 const example = document.querySelector('#myExample');

function addTransition() {
    example.classList.add('transition');
    console.log('addTransition', example);
}

function removeTransition() {
    example.classList.remove('transition');
    console.log('removeTransition', example);
}

const el = document.querySelector('.example');
const output = document.querySelector('#output');

el.addEventListener('transitionend', function() {
    output.textContent = 'Transition ended';
});

document.querySelector("button.add").addEventListener("click", (e) => {
  e.stopPropagation();
  addTransition();
});
document.querySelector("button.remove").addEventListener("click", (e) => {
  e.stopPropagation();
  removeTransition();
});

// Possibly remove this?
document.addEventListener('click', addTransition);  
 .example {
  width: 100px;
  height: 50px;
  background: pink;
  transition-property: transform background;
  transition-duration: 2s;
  transition-delay: 1s;
}

.transition {
  background: cyan;
  width: 200px;
}

.transition::after {
  content: 'Transition class added'
}  
 <div id="myExample" class="example"></div>
<br>
<button class="add">Add</button>
<button class="remove">Remove</button>
<div id="output"></div>  

Вы можете сделать это с помощью этих обработчиков атрибутов, если вы действительно этого хотите:

 const example = document.querySelector('#myExample');

function addTransition() {
    example.classList.add('transition');
    console.log('addTransition', example);
}

function removeTransition() {
    example.classList.remove('transition');
    console.log('removeTransition', example);
}

const el = document.querySelector('.example');
const output = document.querySelector('#output');

el.addEventListener('transitionend', function() {
    output.textContent = 'Transition ended';
});

// Possibly remove this?
document.addEventListener('click', addTransition);  
 .example {
  width: 100px;
  height: 50px;
  background: pink;
  transition-property: transform background;
  transition-duration: 2s;
  transition-delay: 1s;
}

.transition {
  background: cyan;
  width: 200px;
}

.transition::after {
  content: 'Transition class added'
}  
 <div id="myExample" class="example"></div>
<br>
<button onclick="addTransition(); event.stopPropagation();">Add</button>
<button onclick="removeTransition(); event.stopPropagation();">Remove</button>
<div id="output"></div>  

Но я не рекомендую это, не в последнюю очередь потому, что ваши функции должны быть глобальными, а избегать глобальных — это хорошо ™. 😉