【快应用】addEventListener()方法无法监听动画事件
阅读原文时间:2023年08月15日阅读:1

​【关键词】

动画监听、动态改变

【问题背景】

Style中设置动画样式,然后在onshow生命周期中调用addEventListener()方法去监听动画事件,无法监听到,该方法无任何回调返回

问题代码如下:

<template>

  <!-- Only one root node is allowed in template. -->

  <div class="container" id="ani">

    <text class="title" >Hello World</text>

  </div>

</template>

<style>

  .container {

    flex-direction: column;

    justify-content: center;

    align-items: center;

    animation-name: translateX;

    animation-duration: 1000ms;

  }

  .title {

    font-size: 100px;

  }

  @keyframes translateX {

    from {

      transform: translateX(20px);

    }

    to {

      transform: translateX(200px);

    }

  }

</style>

<script>

  import prompt from '@system.prompt';

  module.exports = {

    data: {

      componentData: {},

    },

    onInit() {

      this.$page.setTitleBar({

        text: 'menu',

        textColor: '#ffffff',

        backgroundColor: '#007DFF',

        backgroundOpacity: 0.5,

        menu: true

      });

    },

    onShow(options) {

      '// Do something .'

      console.log("111111111111111111111111111111111");

      var element = this.$element("ani")

      element.addEventListener("animationend", (event) => {

        console.log("22222222222222")

        prompt.showToast({

          message: 'type: ' + event.type + ', animationName: ' + event.animationName + ', elapsedTime: ' + event.elapsedTime

        })

      })

    },

  }

</script>

回调结果如下图所示:

【问题分析】

这是华为与联盟的底层实现差异导致的,华为是需要在动画效果触发前去调用监听方法才能拿到回调结果。而在onshow中调用时,动画效果已经触发,是无法监听到的。如果要获取callback结果,必须先调用addEventListener,然后再动态修改class,触发CSS动画样式效果。

【解决方法】

在动画样式触发之前调用addEventListener监听方法,动画效果的触发可以通过动态改变class来实现,具体代码如下:

<template>

  <!-- Only one root node is allowed in template. -->

  <div class="container {{name}}" id="ani">

    <text class="title">Hello World</text>

  </div>

</template>

<style>

  .container {

    flex-direction: column;

    justify-content: center;

    align-items: center;

  }

  .animation {

    animation-name: translateX;

    animation-duration: 1000ms;

  }

  .title {

    font-size: 100px;

  }

  @keyframes translateX {

    from {

      transform: translateX(20px);

    }

    to {

      transform: translateX(200px);

    }

  }

</style>

<script>

  import prompt from '@system.prompt';

  module.exports = {

    data: {

      componentData: {},

      name: ''

    },

    onInit() {

      this.$page.setTitleBar({

        text: 'menu',

        textColor: '#ffffff',

        backgroundColor: '#007DFF',

        backgroundOpacity: 0.5,

        menu: true

      });

    },

    onShow(options) {

      '// Do something .'

      console.log("111111111111111111111111111111111");

      var element = this.$element("ani")

      element.addEventListener("animationend", (event) => {

        console.log('type: ' + event.type + ', animationName: ' + event.animationName + ', elapsedTime: ' + event.elapsedTime)

        prompt.showToast({

          message: 'type: ' + event.type + ', animationName: ' + event.animationName + ', elapsedTime: ' + event.elapsedTime

        })

      })

      this.name = "animation"

    },

  }

</script>

回调结果如下图所示: