页面中实现动画的四种方式:
目前为止常用的实现页面中动画效果的方式有四种,分别是
1 transition 过渡动画来实现动画效果
2 animation css动画来实现动画效果
3 原生js依靠定时器来封装的动画
4 通过jQuery内置的动画(三组基础动画,和一个自定义动画)来实现效果
其中transition过渡动画,可以在一个页面元素的两个状态之间,自动的实现动画效果
非常的轻便简洁,通过设置transition-propery, duration,timing-function,delay就可以非常轻松的控制动画的各种主要表现;当然缺点也非常的明显,
1 transition过渡动画总是从当前状态出发,去往目标状态,也就是两个状态之间的切换;这让transition很难实现一些复杂的动画;控制transition的样式也是有一点讲究的;定位可以瞬间到位,而transform就不行;所以transition在很多时候控制元素的两个状态,其实没有我们想想的容易
2 transition动画,在面对display: none 和display:block这两个常见的状态切换的时候,是没有任何效果的。包括希望在这两个状态之间添加上额外的属性变化也是没有效果的;transition生效的状态必须是在页面中的显示状态
3 以及css实现的动画一贯的问题,就是属性必须是一致,比如我们用定位方位属性的习惯,一般都是离哪边近用哪边。比如贴左边就用left,贴右边就用right;在这点上,transition实现动画其实还是需要一定的计算的,这点在JS动画里面不明显,其实是因为JS动画(尤其是原生),强调通过累计来实现动画路程,而不是开始和结束的状态;
animation动画则是c3提供的页面样式,8个属性非常的灵活,并且@keyframe自定义动画途中的状态,可以实现各种自动的动画;
使用animation实现往复运动的动画,远比js要方便快捷;JS必须要有Jquery那样的动画队列才比较方便
而在各种单向移动的动画上,我们一般可能都喜欢用JS来实现,但是其实animation通过类名来动态添加,也可以实现相当不错的效果;
例子就是页面中非常常见的盒子飞入效果,我们希望这些盒子飞入尽可能的稳定,并且最好只是一个动画效果。那么其实可以通过设置一个放置动画的类名(这种动画,我个人喜欢用相对定位来做,因为相对定位,它动画的目的地一定是top0 和 left0 。只需要设置一下起始的位置就可以了,并且可以省下transform属性,
原生JS依靠定时器实现的动画效果,其实就是控制一个盒子的属性,让这个盒子分步,在一定时间内抵达设定的目的地;
常见的问题主要是定时器问题,为了保证定时器不会互相冲突。一般的做法就是直接在动画代码的最前面,先清除一下已有的定时器。这种做法可以很好的解决动画之间互相冲突的问题,但是很不利于控制代码的执行次序,比如我们需要在动画结束的时候做一点什么事情;这种情况一般都是在清除定时器的判断中写入一个回调函数,让这个函数在动画到达终点的时候再执行。这比用一个延时器之类的东西更好控制,也更容易调整;但是如果我们清除掉定时器,这个回调函数就永远不可能执行了;
以及反复的开启关闭定时器,会有动画卡顿的问题。这是因为定时器一开始并不是运行的状态
(如果在动画的定时器内再挂载了什么希望有一定执行顺序的代码,那么清除定时器就永远不会执行了)
另一个动画的问题,是动画会把事件触发机制的问题暴露出来;以下拉菜单为例子,即使是一般的下拉和上升都有动画的菜单,因为菜单动画一般都是比较快的,所以在放大镜案例中出现的情况,也就是在父元素里面进入子元素,触发父元素的离开事件,子元素的进入事件,再冒泡到父元素的进入事件;在动画中就会有一个明显的折返
而如果这个菜单是只有下拉动画,离开瞬间消失的,那么这种特性绝对是灾难式的。动画从根本上就不适合这种情况。所以才会有Mouseenter这种救星级别的事件;但是常规的处理方式也不是不行,我个人是通过绕过动画的方式来实现效果;也就是放大镜效果的方式,用瞬间的显示隐藏来替代有一定表现得动画,就可以避免动画的折返,只是整个事件的触发会需要精心设计。这是不使用动画就不会有的问题,所以我觉得还是应该在动画里面讲
JQuery提供的动画非常的好用,尤其是自定义动画;
不过基础动画其实也蛮常用的。看到很多效果都类似基础动画;但是里面需要注意的就是Toggle动画和前面两个的区别。Toggle动画可以实现终止继续的效果,而基础动画不行。基础动画可以确保整个动画的触发一定是想要的效果,而TOGGLE就会有反着来的风险
JQuery的自定义动画也不是没有风险,特别是广泛用上stop方法以后。假如stop了一个动画,那么这个自定义动画里面的回调函数也是不会执行的,假如这个回调函数事关比如轮播图的表现顺序之类关键的效果;就必须要从根源上解决问题(也就是解决掉点那么快的用户了!)