为什么onanimationend在我的代码中不起作用,但是addEventListener(“ animationend”)起作用?

时间:2019-01-28 08:59:23

标签: javascript css css-animations

我试图在元素的淡入淡出动画结束后删除它。将侦听器添加到animationend事件中可以很好地工作,但是不能将处理程序分配给.onanimationend-动画结束时不会触发该函数。 on-处理程序为什么不起作用?

我正在FF 48上运行代码,但是在Chrome 71上也会出现此问题。

const post = document.querySelector('.post');
const hideButton = post.children[0];

// When hide button is clicked, run fade animation.
hideButton.onclick = function() {
  post.style.animationPlayState = "running";
};

// This function runs
post.addEventListener("animationend", function() {
  console.log('animationend listener running');
  // this.remove();
});

// This function doesn't run
post.onanimationend = function() {
  console.log('onanimationend handler running');
  // this.remove();
};
@keyframes hide {
  0% {
    opacity: 1;
    height: 100%;
    margin: 10px 0;
    padding: 15px;
  }
  75% {
    opacity: 0;
    height: 100%;
    margin: 10px 0;
    padding: 15px;
  }
  100% {
    opacity: 0;
    height: 0px;
    margin: 0px;
    padding: 0px;
  }
}

.post {
  background-color: #80ff00;
  margin: 10px 0;
  padding: 15px;
  animation-name: hide;
  animation-duration: 2s;
  animation-fill-mode: forwards;
  animation-play-state: paused;
}
<div class="post">
  Post
  <button class="hide">
    Hide
  </button>
</div>

2 个答案:

答案 0 :(得分:0)

检查您的浏览器版本并与之比较 https://caniuse.com/#search=animationend

  

Firefox v48.0.0 – Java Broker 36分钟前

您的浏览器与animationend不兼容

答案 1 :(得分:0)

这是因为Chrome仍然不支持,而FF 45仍然不支持HTMLElement.onanimationend处理程序。
我无法告知Firefox 45(您应该更新btw),但是Chrome确实支持GlobalEventHandler's onewindow),这说明了为什么通过EventTarget.addEventListener附加的处理程序会捕获到它。 / p>

window.onanimationend = e => {
  // stacksnippet's console also has CSS animations...
  if(e.animationName === 'roundify')
  console.log({ // logging the full event will kill the page
    target: e.target,
    type: e.type,
    animationName: e.animationName
  });
}
#anim {
  width: 100px;
  height: 100px;
  background: #333;
  animation: roundify 2s forwards;
}
@keyframes roundify {
  100% { border-radius: 50%; }
}
<div id="anim"></div>

现在,如果您确实需要HTMLElement和Document处理程序,则可以很好地自己实现,但是请注意,更改此类DOM原型通常是一个坏主意。

// now we only have our Element's event

anim.onanimationend = e => console.log({ // logging the full event will kill the page
    target: e.target,
    type: e.type,
    animationName: e.animationName
  });
#anim{
  width: 100px;
  height: 100px;
  background: #333;
  animation: roundify 2s forwards;
}
@keyframes roundify {
  100% { border-radius: 50%; }
}
<script>
// This does modify both HTMLElement and Document protoypes,
// should be placed at top most position in the doc possible
(function(){
  if(
    !("onanimationend" in HTMLElement.prototype) &&
    window.onanimationend !== undefined
  ) {
    // will attach the handler on a the Object's `__animationendhandler` property
    const getsetanimationend =   {
      get: function() {
        return this._animationendhandler || null
      },
      set: function(func) {
        this.removeEventListener('animationend', this._animationendhandler);
        if(typeof func !== 'function') {
          this._animationendhandler = null;
          return;
        }
        this._animationendhandler = func;
        this.addEventListener('animationend', func);
      }
    };

    Object.defineProperty(HTMLElement.prototype, 'onanimationend', getsetanimationend);
    Object.defineProperty(Document.prototype, 'onanimationend', getsetanimationend);
  }
})();
</script>
<div id="anim"></div>