【问题标题】:Why doesn't onanimationend work in my code, but addEventListener("animationend") does?为什么 onanimationend 在我的代码中不起作用,但 addEventListener("animationend") 起作用?
【发布时间】:2019-06-21 05:55:03
【问题描述】:

我正在尝试在元素的淡入淡出动画结束后删除它。向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>

【问题讨论】:

  • 我可以在 Chrome 71 上重现该问题。该元素看起来在 FF 56 上已被正确删除。听起来像是浏览器问题,而不是您的代码问题。
  • 是的,其实是浏览器的问题。我编辑了我的答案。

标签: javascript css css-animations


【解决方案1】:

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

Firefox v48.0.0 – Java Broker 36 分钟前

您的浏览器不兼容animationend

【讨论】:

  • 对不起,我不够清楚。我不想同时运行 2 个事件处理程序。我只是举了一个例子,一个函数有效,另一个函数无效。用于比较目的。
  • onanimationend 在我的代码中不起作用。即使我只是在控制台上记录一些东西。但是,如果我改用 addEventListener,它就可以正常工作。
  • 您使用哪种浏览器?
  • Firefox v48.0.0
  • 我可以在检查 DOM 属性时看到该属性,并且根据 MDN 有完全支持:developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/…
【解决方案2】:

这是因为 Chrome 仍然不支持,FF 45 仍然不支持HTMLElement.onanimationend 处理程序。
我不知道 Firefox 45(你应该更新 btw),但 Chrome 确实支持 GlobalEventHandler's one (window),这解释了为什么通过 EventTarget.addEventListener 附加的处理程序会捕获它。

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%; }
}
&lt;div id="anim"&gt;&lt;/div&gt;

现在,如果您真的需要 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-29
    • 2014-01-23
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多