首頁 > web前端 > css教學 > 使用 Angular 實作幾乎無限滾動

使用 Angular 實作幾乎無限滾動

Patricia Arquette
發布: 2025-01-07 20:15:41
原創
518 人瀏覽過

無限滾動已經存在了一段時間了。 基本想法:當您滾動時,新內容會在底部加載,從而創建看似無窮無盡的滾動。 實作起來很簡單,但如果沒有仔細規劃,效能就會受到影響。 經過幾次內容重新獲取後,您可能會擁有數百個 DOM 元素,其中許多元素是看不見的。 幸運的是,存在一些模式可以緩解這種情況,我們將使用 Angular 來探索一種模式。

Virtually Infinite Scrolling with Angular

這是我們想要避免的。

虛擬滾動

虛擬滾動在任何時候僅渲染大列表的子集——與無限滾動不同。 它非常適合一次渲染所有內容效率低下的大型資料集。 僅渲染可見(和近乎可見)的項目;當使用者捲動時,項目會動態交換。 這顯著減少了 DOM 元素,從而提高了效能。

虛擬滾動透過建立與視窗高度匹配的容器來運作。 只有可見項目(加上緩衝區)才會在此容器中以特定的滾動深度呈現,並透過 CSS 進行管理。 捲動更新容器,顯示新項目並刪除視圖以外的項目,調整滾動深度。 將此與無限滾動相結合,創建一個幾乎無限的列表,而不會造成效能損失。

下面的範例顯示了包含數千個項目的列表,但一次最多渲染 8 個。 滾動會調整 CSS 滾動高度,產生列表更長的錯覺。

Virtually Infinite Scrolling with Angular

現實世界的例子

讓我們建立一個 Angular 應用程序,從 Reddit 的分頁 API 獲取媒體並將其顯示在虛擬滾動列表中。 它將包括一個用於子 Reddit 選擇的搜尋欄和一個過濾器。 向下捲動可載入更多內容。 我們的關鍵要求:

  1. 由 RxJS Observables 和非同步管道驅動。
  2. 在 subreddit 或過濾器更改時重置內容,但不會在附加新內容時重置內容。
  3. 將先前的內容儲存在記憶體中,以便無縫向上/向下捲動,無需多餘的 API 呼叫。

我們將使用 @angular/cdk 套件(包含 Virtual Scroller 元件)。使用npm i @angular/cdk安裝它。

雖然此範例使用 Angular,但類似的模式也適用於 React、Vue 或 vanilla JavaScript。 此處提供了說明基本原理的基本示範。

服務設定

首先,我們建立一個服務,使用 Angular 的 HttpClient 和 RxJS Observables 從 Reddit API 取得內容來管理 subreddit 名稱和過濾器。 (為簡潔起見,省略了一些程式碼;完整的實作在這裡)。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

內容取得方法在資料請求期間追蹤特定屬性。 page 屬性被加入到查詢字串中,以確保在最後一項之後取得新內容。 我們也過濾掉 NSFW 內容和缺少貼文提示的項目。這可確保僅顯示預期的內容。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

query$ observable(之前被省略)在取得內容之前合併不同的 observable 流。 scan 運算子結合了先前和目前的串流結果,建立跨多個頁面的大型資料數組。

這允許廣泛滾動;只有 subreddit 名稱或過濾器更改才會觸發完整的重新獲取。 nextPagequery$ 的屬性,儲存目前集合中的最後一個項目 ID,用於確定在接近虛擬捲軸底部時要取得的下一頁。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

RxJS 的強大之處在於組合和操作資料流。這使我們能夠在業務邏輯到達元件之前對其進行處理,從而使元件保持清潔和可重複使用。

組件設定

接下來,我們使用 Angular 的 CdkVirtualScrollViewport 設定元件來顯示內容。 一個方法處理視窗底部附近的滾動,透過 subRedditPage$ observable 取得下一頁。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

範本使用非同步管道訂閱query$。 注意:隨著內容高度可變,虛擬捲軸變得更加複雜;為了提高效能,建議使用一致的物品高度。

<code class="language-html">// ... (Omitted for brevity) ...</code>
登入後複製

當使用者接近底部時,onScroll 方法會取得更多內容。它使用 nextPage ID(來自 query$)並發送到 subRedditPage$,觸發下一個 API 呼叫並透過 query$ 更新清單。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

搜尋列和選項卡控制項也整合在一起(下面的簡化範例)。

<code class="language-typescript">// ... (Omitted for brevity) ...</code>
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製
登入後複製

結論

這會創造一個幾乎無限的捲軸。 您可以在此處進行測試。 Reddit 的 API 有速率限制;你可能會在測試過程中碰到它們。 有關更多詳細信息,包括其他功能,請參閱 GitHub 存儲庫此處

以上是使用 Angular 實作幾乎無限滾動的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板