天天看點

Angular 實作清單自動滾動

前言

實作新聞清單自動滾動,類似中獎名單那種滾動,目前 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';
}