时间:2021-05-18
加入“动效”是让用户对应用的行为进行感知的一种有效手段。“列表”是应用中最常使用的一种界面形式,经常会有添加行,删除行,移动行这些操作。设想添加的操作很简单,删除时从大到小,然后消失;添加时从小到大;移动就是先删除再添加。感觉上并不复杂,应该利用CSS的transition就能搞定,可是实际做起来发现有不少问题要处理,下面一一道来。
来些简单的测试
1、最初的版本
<div class='list'> <div class='row-1'>row-1</div> <div class='row-2'>row-2</div></div>.list{margin:20px;background:#eee;font-size:18px;color:white;}.row-1{background:green;overflow:hidden;padding:15px;}.row-2{background:blue;padding:15px;}.demo-1 .remove{-webkit-transition: height 3s linear;}.demo-1 .remove.active{height:0;}var ele = document.querySelector('.demo-1 .row-1');ele.classList.add('remove');ele.classList.add('active');想法很简单,通过添加“remove”类,设置动画的效果,添加“active”修改css属性,激活动画。
结果和想的不一样,两个问题:1、动画并没有运行;2、row-1并没有消失。为什么?首先,CSS的transition不能作用于auto的属性,因为row-1本来并没有设置height,所以不会产生从现有的高度变到0的动画。第二,height=0只是设置了content区域为0,padding并没有改变,所以还是row-1还是占据了30px的空间。
2、指定固定的height并且padding也加上动画
调整CSS
.demo-2 .row-1{height:48px;}.demo-2 .remove{-webkit-transition: height 3s linear, padding-top 3s linear;}.demo-2 .row-1.remove.active{height:0;padding-top:0;padding-bottom:0;}这次的效果是对的,row-1从48px边到0,同时padding也跟着变。
3、还有没有别的办法呢?一定要指定height吗?transform行不行
修改CSS
.demo-3 .remove{-webkit-transition: -webkit-transform 3s linear,padding 0s linear 3s;}.demo-3 .row-1.remove.active{-webkit-transform-origin:0 0;-webkit-transform:scaleY(0);}
即使没有设置height,通过transform执行动画也是没有问题的。问题是,row-1还在原来的地方,还占着空间,row-2并没有向上挪。由此带来个问题,动画执行完了(包括第2个设置height的例子),row-1并没有删除掉,只是看不见了。
4、解决动画执行完清除元素的问题
修改CSS
复制代码 代码如下:
.demo-4 .remove{-webkit-transition: height 3s linear, padding 3s linear, opacity 3s linear,color .5s linear;}
.demo-4 .row-1.remove.active{padding-top:0;padding-bottom:0;color:rgba(0,0,0,0);opacity:0;}
修改JS
var ele, l;ele = document.querySelector('.demo-4 .row-1');l = ele.addEventListener('webkitTransitionEnd', function(evt){ if (evt.propertyName === 'height') { ele.style.display = 'none'; ele.style.height = ''; ele.removeEventListener('webkitTransitionEnd', l, false); }}, false);ele.style.height = ele.offsetHeight + 'px';ele.classList.add('remove');$timeout(function(){ ele.classList.add('active'); ele.style.height = '0px';});这次的效果不错。有几个注意的地方:1、通过注册transitionEnd事件可以捕获到动结束;2、可以同时执行多个动效,每个东西结束都会产生transitionEnd事件,通过事件的“propertyName”可以知道是哪个属性的动效结束了。
5、用velocity.js也试了一下
CSS不用设置
JS代码
看了看执行的过程,也是修改height和padding。但是,velocity用的是requestAnimationFrame函数。我认为如果动效比较简单,就不用引入其他的库了,直接写出来的运行效果差不多。
6、高度搞明白了,变宽度呢?
调整CSS
.demo-6 .row-1{width:100%;}.demo-6 .remove{-webkit-transition: width 3s linear;}.demo-6 .row-1.remove.active{width:0%;}虽然宽本身可以通过百分比进行设置,但是height不固定的问题还是存在。
7、用上JS解决变width的问题
设置CSS
.demo-7 .row-1{width:100%;height:48px;}.demo-7 .remove{-webkit-transition: width 3s linear, opacity 3s ease;}.demo-7 .row-1.remove.active{width:0%;opacity:0;}固定了height已有动效正常了。其他的改进可参照前面的例子了。
二、一个完整的例子
完整的例子实在angular中实现的。angular实现首先一个问题就是在什么时机设置动效?因为,angular是双向绑定的,如果在controller中删除了一个对象,渲染界面的时候这个对象就没了,所以必须介入到数据绑定的过程中。angular提供ngAnimatie这个动画模块,试了一下它也确实可以完成ngRepeat列表数据更新的动效。但是要额外引入angular-animation.js,虽然不大,还是觉得不是很有必要。另外,我是在一个已经写好的框架页面上加动画,如果需要引入新的module,需要改框架文件,我觉得不好。试了试动态加载animation模块也没成功,所以就研究了一下自己怎么控制动效。
angular即使不加载animation模块,也有一个$animate,它为动效控制留出了接口。
看JS
ng-repeat进行数据更新是会调用$animate服务的enters,leave和move方法,所以,要自己控制动效就要重写对应的方法。重写的时候要用$animate添加,直接在dom上设置有问题。(这一段的angular的逻辑比较底层,没有太看明白,还需要深入研究。)
另外,在移动行的位置时,要通过$timeout将删除和插入放到两个digest循环中处理,否则看不出效果。
var index = records.indexOf($scope.selected), r = records.splice(index, 1);$timeout(function(){ records.splice(index + 1, 0, r[0]);},500);angular的动画和digest循环关系密切,看了angular-animation.js的代码没看明白,还需要深入研究才行。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Angular4.0动画操作。分享给大家供大家参考,具体如下:粗略的记录一下angular4的动画先看一下angular中文网关于这个给的例子。有
总结一下自己给编辑器定制样式的过程中所遇到的问题,主要是编辑器的二次开发接口,以及用angular定制样式,问题不少,终于在**的帮助下,完成了,还剩下老版本和
ng-animate本文讲一下Angular中动画应用的部分。首先,Angular本生不提供动画机制,需要在项目中加入Angular插件模块ngAnimate才
遇到一个问题:给模态框加入退出动画,进入的动画效果是有的,可是退出的动画就没有了。写个简单的结构: 请登录 .mask是遮罩层,
刚搭建完一个webpack+angular2环境,由于angular及webpack官网上没有一个折中的搭建方案,所以只能摸索着搭建,中间遇到一些坑,遂总结记录