重复执行 transitionend 事件

Duplicated executions of transitionend event

我想了解为什么以下代码以指数方式重复 transitionend 的 return。

这对我来说没有任何意义,因为它们应该具有相同的行为并且应该只执行一次。

下面评论了预期的行为。

(function() {
  var animations = {
    start: function() {
      console.log('animations has started');
      this.transition.run();
    },
    transition: {
      duration: 500,
      run: function() {
        console.log('transitions is running');
        const el = document.querySelector('.box');
        el.classList.toggle('fadein');
        // dont duplicate as expected !!!GOOD BEHAVIOR!!!
        /*el.ontransitionend = function(){
          console.log('transitionend triggered!');
        };*/
        // duplicates at every click !!!BAD BEHAVIOR!!!
        el.addEventListener('transitionend', function() {
          console.log('transitionend triggered');
        }, false);
      }
    }
  };
  const bt = document.querySelector('button');
  bt.addEventListener('click', () => {
    animations.start();
  })
})();
.box {
  width: 100%;
  height: 100vh;
  background: green;
  opacity: 0;
  transition: opacity .5s linear;
}

.box.fadein {
  opacity: 1;
}
<button>Start Transition</button>
<div class="box"></div>```

真是奇怪的行为!

来自MDN event handler docs

To set event handler code you can just assign it to the appropriate onevent property. Only one event handler can be assigned for every event in an element. If needed the handler can be replaced by assigning another function to the same property.

The most flexible way to set an event handler on an element is to use the EventTarget.addEventListener method. This approach allows multiple listeners to be assigned to an element, and for listeners to be removed if needed (using EventTarget.removeEventListener).

这是什么意思?

使用 el.ontransitionend,您总是替换“旧”事件处理程序,因为只能有一个 属性 处理程序。
但是使用 el.addEventListener 你总是添加一个新的处理程序,只要你不明确删除它,旧的将保持不变。