前言
實作新聞清單自動滾動,類似中獎名單那種滾動,目前 js 實作的方式還是有很多相關代碼的,不過這裡使用 Angular 實作,其實原理差不多,正好業務需要,在此記錄下如何實作。
正文
實作思路:
1. 擷取頁面的元素操作其滾動條
2. 當滾動條距離底部還有 10 個像素内,需要将滾動清單再次追加
3. 當追加次數過多時,需要重新開始,防止頁面卡頓(這也是體驗不好的地方,如果有其他更好的方案歡迎留言)
HTML:
- 定義一個 div 并設定寬高
- 設定是否可以手動滾動 根據滑鼠移入移出來決定
<div #scroller class="scroller-css" [ngStyle]="{'overflow': scrollerOverflow}" (mouseenter)="mouseEnterScroll()" (mouseleave)="mouseLeaveScroll()">
<div *ngFor="let item of list">
<!-- 清單顯示内容 -->
<div>{{ item }} ------- {{ item }}</div>
</div>
</div>
CSS:
- 設定内部 div 的高度及定位
.scroller-css {
position: relative;
height: 200px;
}
/** 隐藏滾動條 */
.scrollerCss::-webkit-scrollbar { width: 0 !important }
TS:
// 資料清單,可以從接口擷取
list = ['test', 'temp', 'demo', 'test', 'temp', 'demo', 'test', 'temp', 'demo'];
// 記錄最原始的資料清單,保證資料不會被更新掉
listOrigin = [];
// 滾動清單
@ViewChild('scroller', {static: false}) scroller: ElementRef;
// 是否允許手動滾動
scrollerOverflow: string = 'hidden';
timer: any;
// 擷取資料清單,如果是伺服器擷取資料,可以在擷取完資料後執行
getList() {
this.listOrigin = [...this.list];
this.scrollerFn();
}
// 初始化擷取資料
ngOnInit () {
this.getList();
}
// 當元件銷毀時,移除定時器
ngOnDestroy(): void {
clearInterval(this.timer);
}
// 滾動清單方法
scrollerFn() {
// 擷取頁面元素
const element = this.scroller.nativeElement;
// 記錄清單追加次數
let times = 1;
// 開始循環滾動
this.timer = setInterval(() => {
element.scrollTop++;
const marginBottom = element.scrollHeight - element.scrollTop - element.clientHeight;
// 如果目前滾動到底 10px 時追加資料
if (marginBottom < 10) {
this.list.push(...this.listOrigin);
times++;
}
// 如果追加了 10 次以上,重新開始滾動,防止頁面元素過多,這就是為什麼需要另外一個變量的原因
if (times > 10) {
this.list = [...this.listOrigin];
element.scrollTop = 0;
times = 1;
}
}, 50); // 50 ms 滾動一次,基本是平滑滾動,再大一點就有點卡卡的感覺了
}
// 滑鼠移入停止滾動
mouseEnterScroll() {
clearInterval(this.timer);
// 允許手動滾動
this.scrollerOverflow = 'auto';
this.scroller.nativeElement.scrollTop = 0;
this.list = [...this.listOrigin];
}
// 滑鼠移出開始滾動
mouseLeaveScroll() {
this.scrollerFn();
// 采用自動滾動,隐藏滾動條
this.scrollerOverflow = 'hidden';
}