Vue/Uniapp实现JS动态重复执行原生Animation动画

序言

相信我们偶尔会遇到一种需求,按下某个按钮,触发事件,事件回调里让某个元素执行CSS定义好的Animation动画。

首先这个动画是绑定在元素的Class属性来对动画进行定义,会在第一次加载时执行。但我们的需求明显不需要他上来就执行。我们需要动态执行并且能重复执行

那么如何实现呢,在网上查找到的方法基本都是拿到元素后,使用JQuery的removeClass来控制样式的清除。但是Vue不建议进行dom元素的操作,甚至uniapp里没有Window,自然没有document函数库更还拿不到到元素(特别view),那我们怎么退而求其次呢。

不浪费大家时间 先给出总结

v-bind元素上绑定class--->nextTick中执行清除data中的class--->异步执行赋值data中的class

详细分析

首先给出前置的代码 这里用的uniapp展示,因为他限制最大最麻烦,其他vue的可以照葫芦画瓢更方便。 

<!-- HTML部分 -->
<view :class="className">切入动画实践</view>
<button  @click="changeClass()">点击动画</button>

动画是网上找的,太长就省略了

    @-webkit-keyframes shake {
    ...
	}
	
	@keyframes shake {
	...
	}
	
	.shake {
	  -webkit-animation-name: shake;
	  animation-name: shake;
	}
	
	.animated {
	  -webkit-animation-duration: 1s;
	  animation-duration: 1s;
	  -webkit-animation-fill-mode: both;
	  animation-fill-mode: both;
	}

接下来是JS

data() {
	return {
		classname:''
	}
},
methods:{
	changeClass(){
    	this.classname=''//清空样式
		this.classname='animated shake'//设置动画
	}
}

首先是绑定用的classname自然不用说,动态绑定能让我们后续可以绑上想要实现的动画,关键在于如果我们直接使用按钮绑定的回调,直接更改classname,那么我们会发现什么变化都没有。

因为我们修改了classname,导致回流,这也是实现动画执行的一环。但问题是,目前的修改是不会显示在页面上的,此时操作DOM,只会更改在虚拟dom中,而vue还没更新页面。

那我们都应该知道此时应该使用nextTick()来延迟执行对dom的操作。此处本人表述不清,不太懂nextTick应用场景的朋友请自行官网观看深入响应式原理 — Vue.js

data() {
   return {
	classname:''
	}
},
methods:{
	changeClass(){
		this.$nextTick(function(){
		this.classname=''//清空样式
		this.classname='animated shake'//设置动画
	 })
  }
}

设置完后,我们点击按钮,理应看到动画执行了,实际上动画的确执行了。但是当我们再次点击时就会发现,动画并没有执行,这是为什么呢? 

 

原因就在于 Class="animated shake" 切换为Class="" 再切换成Class="animated shake"连续一起了,而回流和动画执行都是JS执行完后,才判定是否改变,需不需要回流,异步执行的,所以根本没有监测到Class改变了。所以非常简单 ,我们再给Class="animated shake"嵌套一个异步即可。

data() {
	return {
		classname:''
	}
},
methods:{
	changeClass(){
	let that=this//如果定时器用普通函数就需要that哦,不然拿不到this
	this.$nextTick(function(){
	this.classname=''//清空样式
	setTimeout(()=>{
	that.classname='animated shake'//设置动画
	},0) 
   })
 }
}

当然你也可以不使用nextTick,使用两个定时器一样可以实现。原理就是两个异步,第一次延迟设置样式看到回流后的效果,第二次隔开清除样式再次设置动画。

现在我们可以很舒服的通过JS动态绑定我们要的动画样式,并且重复执行。类似的Dom操作也可以从此得到启发,至于测试其他情况就请大家去尝试尝试啦!~

猜你喜欢

转载自blog.csdn.net/weixin_43818307/article/details/124800668