Почему onanimationend не работает в моем коде, а addEventListener ("animationend") работает? - PullRequest
0 голосов
/ 28 января 2019

Я пытаюсь удалить элемент, как только закончится анимация исчезновения.Добавление слушателя к событию 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 голосов
/ 29 января 2019

Это потому, что Chrome все еще не поддерживает FF 45 и не поддерживает обработчик HTMLElement.onanimationend.
Я не могу сказать для Firefox 45 (что вам следует обновить btw), ноChrome поддерживает GlobalEventHandler's (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%; }
}
<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>
0 голосов
/ 28 января 2019

Проверьте версию своего браузера и сравните с https://caniuse.com/#search=animationend

Firefox v48.0.0 - Java Broker 36 минут назад

Ваш браузер не совместим с animationend

...