成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

太長了,巧妙地優化了跑馬燈

開發 前端
用animation雖然好,但是不能控制跑馬燈的長度,即我不想讓50個item一起滾動,最好是讓只需要出現在屏幕中的item滾動就好了。于是就將滾動改成了item為絕對定位,然后利用transform來改變位置,然后利用transition來實現動畫的過渡。

前言

上周優化了個跑馬燈,原因是跑馬燈的長度太長了,每個item的節點比較多,所以即使限制最多只有50個item,也還是很長很長,有多長可以看看下面

圖片圖片

怎么優化呢?看看之前的跑馬燈。

優化前的寫法

圖片圖片圖片

之前的寫法很簡單,其實就是讓很長很長的class="animate"的div在lottery-person-wrapper中滾動。用的是css 中的animation屬性。

用animation雖然好,但是不能控制跑馬燈的長度,即我不想讓50個item一起滾動,最好是讓只需要出現在屏幕中的item滾動就好了。于是就將滾動改成了item為絕對定位,然后利用transform來改變位置,然后利用transition來實現動畫的過渡。

優化后的寫法

圖片

可以看到沒有那么多的item節點了,這是怎么辦到的呢?

  1. 首先獲取lottery-person-wrapper的寬度。
this.animationWrapperWidth = this.$refs.animateWrapper.clientWidth;
  1. 然后再讓一個item出現在跑馬燈中。
mounted() {
this.$nextTick(() => {
this.animationWrapperWidth = this.$refs.animateWrapper.clientWidth;
this.emitItem();
});
}
  1. 看看emit是怎么寫的。

首先需要知道:

  • swiperUserList是從接口獲取到的列表。
  • swiperUserListShow是在template中遍歷的列表。

圖片圖片

我們先拿出swiperUserList中的第一個item,然后再把item放入swiperUserList的尾部,讓swiperUserList始終保持50個item。

然后,再把這個item深拷貝放入到swiperUserListShow中,為什么要深拷貝是因為,不希望swiperUserListShow的item與swiperUserList中的item出現引用的關系,否則會十分混亂。

給每一個item添加了一個id是為了作為遍歷時獨一無二的key。

圖片圖片

接下來則是要獲取該item的寬度clientWidth,然后計算出該item的尾部出現的時間endShowTime,以及該item完全走完消失的時間disappearTime。

在該item尾部出現的時候,就讓下一個item push到swiperUserListShow中,使其出現在跑馬燈中,在該item完全跑完消失的時候就讓這個item從swiperUserListShow中剔除。

emitItem() {
if (!this.isShow) {
return;
}
let swiperUser = this.swiperUserList.shift();
this.swiperUserList.push(swiperUser);
this.swiperUserListShow.push(
Object.assign({}, { ...swiperUser, id: this.swiperId })
);
this.swiperId += 1;
this.$nextTick(() => {
let elm = this.$refs.swiperUserList[this.swiperUserListShow.length - 1];

let elmWidth = elm.clientWidth || 0;

let disappearTime = (elmWidth + this.animationWrapperWidth) / 60;
let endShowTime = elmWidth / 60;

let moveItem =
this.swiperUserListShow[this.swiperUserListShow.length - 1];
elm.style.transition = `transform ${disappearTime}s linear`;
elm.style.transform = 'translate(-100%,-50%)';
// this.clearTimer(moveItem)
moveItem.endShowTimer = window.setTimeout(() => {
clearTimeout(moveItem.endShowTimer);
moveItem.endShowTimer = null;
this.emitItem();
}, endShowTime * 1000);

moveItem.disappearTimer = window.setTimeout(() => {
clearTimeout(moveItem.disappearTimer);
moveItem.disappearTimer = null;
this.swiperUserListShow.shift();
}, disappearTime * 1000);
});
},

基本上就已經實現了。

為什么說是基本?

因為有兩個坑。

看看坑

第一個是我們用了setTimeout,在我們將頁面切到后臺的時候,setTimeout里的代碼是掛起的,不會執行,但是頁面上的動畫還是會繼續執行的。

elm.style.transition = `transform ${disappearTime}s linear`;
elm.style.transform = 'translate(-100%,-50%)';

所以,為了解決這個bug,需要監聽是否切出切入后臺,切到后臺則清除所有setTimeout和清空swiperUserListShow列表,切回頁面,再重新執行emitItem。

mounted() {
this.$nextTick(() => {
this.animationWrapperWidth = this.$refs.animateWrapper.clientWidth;
this.emitItem();
});

// 處理退出前臺,跑馬燈還在跑的問題,隱藏就是直接清空展示列表
document.addEventListener('visibilitychange', () => {
const isShow = document.visibilityState === 'visible'
this.handleSwiperListShow(isShow);
});
}
methods: {

// 處理跑馬燈展示列表和清除計時器
handleSwiperListShow(isShow) {
if (isShow) {
this.emitItem();
} else {
this.swiperUserListShow.forEach((item) => {
clearTimeout(item.endShowTimer);
clearTimeout(item.disappearTimer);
});
this.swiperUserListShow = [];
}
},
}

第二個坑是我們使用了clientWidth來獲取item的寬度,當我們頁面中有tab的時候,并且跑馬燈在某個tab下,然后當前v-show是激活的是其他tab,則會導致跑馬燈被隱藏,則獲取不到item的寬度,這時的clientWidth的值為0.導致計算出來的endShowTime的值為0,則會導致瘋狂執行settimeout里面的內容。

為了解決這個bug則需要在父組件中傳入isShow來判斷跑馬燈這個頁面是否被隱藏。

props: {
isShow: {
type: Boolean,
default: false
},
}

然后監聽isShow。

watch: {

// 處理tab選項卡隱藏抽獎模塊,獲取不到item clientWith的問題,隱藏就是直接清空展示列表
isShow(newVal, oldVal) {
this.handleSwiperListShow(newVal)
}
},

至此,優化過程就到此完美結束了。

其實還有個比較簡單的優化方法,但是不適用于我這個場景,但是也分享一下。

就是依然使用css的animation動畫屬性,然后使用animationEnd的監聽事件。

圖片

其他優化方案

當監聽到結束的時候,利用v-if把當前跑馬燈銷毀,然后就往swiperUserListShow中push兩個item,再生成展示跑馬燈,又實現animation動畫,這樣是一個實現起來十分方便的方案,但是由于同一時刻只有我們push的item數,而且需要跑完才繼續展示下兩個,會留下一片空白,就有的不連貫的感覺,所以不使用這種方案。

圖片

責任編輯:姜華 來源: 前端陽光
相關推薦

2015-08-07 15:45:02

swift跑馬燈源碼

2011-07-29 10:01:21

IOS 跑馬燈

2013-01-14 17:18:43

Android開發TextView跑馬燈效果

2023-11-01 08:33:45

CSS動畫效果

2025-04-14 09:35:00

2021-01-28 14:34:35

鴻蒙HarmonyOS應用開發

2017-11-10 11:04:29

NVIDIA TITA處理器典藏版

2021-01-29 09:48:17

鴻蒙HarmonyOS應用開發

2021-04-16 05:54:05

CSS 文字動畫技巧

2022-10-26 11:00:06

VisualC++函數

2020-08-12 09:53:18

代碼開發工具

2014-12-31 15:42:21

Android多線程軟件下載

2021-02-14 14:06:24

SQL數據庫面試

2020-05-28 09:06:23

大數據平臺優化

2011-01-13 16:11:13

silverlightwebasp.net

2023-09-06 10:44:09

Nitrux 3.0工具

2020-10-22 10:15:33

優化Windows電腦

2021-07-28 14:35:09

代碼進度條前端

2013-10-22 09:28:39

廣域網優化 路由器WAN

2021-02-18 11:56:43

惡意軟件勒索軟件網絡攻擊
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲a毛片| 国产成人在线视频免费观看 | 视频一区二区在线观看 | 青青草av网站 | 亚洲精品久久久 | 黄色毛片免费看 | 视频在线一区二区 | 日韩精品网站 | 成人二区| 日韩欧美天堂 | 一级黄a视频 | 日韩色综合 | 视频一区二区中文字幕日韩 | 中文字幕一区二区三区在线观看 | 亚洲精品一区二区在线观看 | 国产成人av在线播放 | 视频1区2区| 亚洲一区二区三区欧美 | 日韩毛片免费看 | 国产激情一区二区三区 | 国产日韩欧美二区 | 国产99久久久国产精品 | 污视频免费在线观看 | 免费国产一区二区 | 国产精品国产a级 | 91精品国产综合久久福利软件 | 五十女人一级毛片 | 亚洲一区免费 | 高清一区二区三区 | 成人a网 | 综合国产 | 欧美日韩一区二区在线播放 | 国产激情一区二区三区 | 久久福利电影 | 日本电影韩国电影免费观看 | 国产精品久久久久无码av | 国产精品国产成人国产三级 | 在线日韩在线 | 男人天堂色 | 综合国产 | 免费看91 |