最近看了看人氣眼的界面,感受到學習的地方有不少呀。這裏先帶你們看看人氣值跳動的實現。本篇代碼基於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
喜歡本文的小夥伴們,歡迎關注個人訂閱號超愛敲代碼,查看更多內容.