最近看了看人气眼的界面,感受到学习的地方有不少呀。这里先带你们看看人气值跳动的实现。本篇代码基于Vue2.x.x。函数
首先看一下效果图:学习
要想实现上面的效果,咱们分为这几个部分:优化
首先咱们要先获取元素的位置信息,这里咱们采用getBoundingClientRect方法,MDN上对于该方法的介绍。而后咱们只要与可视区域作个比较,就OK了。动画
// methods
isElementInViewport (el, offset) {
const h = offset || 20,
box = el.getBoundingClientRect(),
top = (box.top >= 0),
left = (box.left >= 0),
bottom = (box.bottom <= (window.innerHeight || document.documentElement.clientHeight) + h),
right = (box.right <= (window.innerWidth || document.documentElement.clientWidth) + h);
return (top && left && bottom && right);
}
复制代码
接下来咱们须要监听'scroll'事件,判断元素是否出如今可视区域内。对于scroll事件的优化之一,咱们须要使用函数节流。你能够选择导入underscore.js的throttle函数,可是这里我尝试了一下requestAnimationFrame来实现函数节流:ui
//mounted:
document.addEventListener('scroll', this.onScroll , false);
// methods:
onScroll (e) {
if (!this.LOCK) {
this.LOCK = true;
window.requestAnimationFrame(this.scrollAction);
}
},
scrollAction () {
const flag = this.isElementInViewport(this.$refs.zfbitem, 100);
if (!flag) {
this.LOCK = false;
} else {
//触发元素高度过渡动画
this.active = true;
//去除掉事件监听
document.removeEventListener('scroll', this.onScroll , false);
}
}
复制代码
在CSS当中,实现一种动画效果,你能够有不少种方式,这里我也就不一一枚举了,此例子中我采用高度过渡的方式实现效果。有人就会说经过高度过渡没有任何难度啊?实际上,你须要注意的点仍是蛮多的:this
实现的代码仍是很简单的,这里就不贴代码了。spa
首先咱们须要在高度过渡动画完成后执行数字跳动动画,这里咱们须要监听'transitionend'事件,对于这个事件须要特别注意的点:3d
// watch :
active (newValue) {
if (newValue) {
this.$refs.zfbitem.addEventListener('transitionend', this.transitionAction, false);
}
}
// methods:
transitionAction (e) {
//再也不须要监听时,必定要移除监听
this.$refs.zfbitem.removeEventListener('transitionend', this.transitionAction, false);
this.numberBounce();
}
复制代码
对于数字跳动的动画,正好利用了Vue响应式的特性偷懒了一波,感受实现的仍是有些生硬,我主要是从这几个方面下手的:code
//组件须要传入的参数
props: {
rate: Number
}
//分割个位 和 十位
computed: {
numberArray () {
return (this.rate + '').split('');
}
}
numberBounce () {
let arr = this.numberArray,
totalTime = 200,
a = arr[1],
aLen = Number.parseInt(a),
aTime = Math.floor(totalTime / (aLen + 9)),
i = 0,
b = arr[0],
bLen = Number.parseInt(b),
bTime = Math.floor(totalTime / (bLen + 9)),
j = 0;
this.bit = 0;
this.ten = 0;
this.bitTimeId = setInterval(_ => {
i++;
this.bit = i % 10; // 计数
if (i - 10 === aLen) {
//千万不要忘记清除定时器哦
clearInterval(this.bitTimeId);
this.bitTimeId = null;
}
}, aTime);
this.tenTimeId = setInterval(_ => {
j++;
this.ten = j % 10;
if (j - 10 === bLen) {
clearInterval(this.tenTimeId);
this.tenTimeId = null;
}
}, bTime);
}
复制代码
这虽然是一个简单的效果,可是包含的知识点不少,这里又要强调了:基础非常重要,千万不要浮躁。(^_^)cdn
喜欢本文的小伙伴们,欢迎关注个人订阅号超爱敲代码,查看更多内容.