欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

原生JS實現虛擬列表(不使用Vue,React等前端框架)

freeflydom
2025年3月20日 9:22 本文熱度 378

1. 什么是虛擬列表

虛擬列表(Virtual List)是一種優化長列表渲染性能的技術。當我們需要展示成千上萬條數據時,如果一次性將所有數據渲染到DOM中,會導致頁面卡頓甚至崩潰。虛擬列表的核心思想是:只渲染可視區域內的數據,而不是渲染所有數據

 

2. 使用場景

虛擬列表適用于以下場景:

  • 大數據量展示:如聊天記錄、新聞列表、商品列表等需要展示大量數據的場景
  • 無限滾動:需要支持用戶持續滾動加載更多內容的場景
  • 性能敏感:在低性能設備上運行的應用,需要盡可能減少DOM操作
  • 實時數據更新:頻繁更新的數據列表,如股票行情、實時監控數據等

(我覺得實際場景中,分頁會用到更多,用戶要看的數據,永遠只是一小部分,就那么幾條,找不到就用搜索

但總要學學)

 

3. 虛擬列表原理

一句話:

 

要看了,再渲染

 

對,就這么簡單,下面,進行分步

  • 計算可視區域:確定用戶當前可以看到的視口范圍
  • 計算可見項:根據視口位置、每項高度,計算出當前應該顯示哪些數據項
  • 渲染可見項:只渲染計算出的可見項到DOM中
  • 位置偏移:通過CSS定位,確??梢婍椩谡_的位置顯示
  • 監聽滾動:當用戶滾動時,重新計算可見項并更新DOM

這里幾個難點:
我怎么知道哪些數據進入了可視區域?
答:監聽滾動距離,滾到哪,就從哪里開始

 

 

4. 實現虛擬列表

Demo.html代碼如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原生JavaScript虛擬列表實現</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        .list-container {
            position: relative;
            height: 400px;
            overflow: auto;
            border: 1px solid #ccc;
            margin: 20px auto;
            width: 80%;
        }
        
        .list-phantom {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            z-index: -1;
        }
        
        .list-content {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            overflow: hidden;
        }
        
        .list-item {
            padding: 10px;
            border-bottom: 1px solid #eee;
            color: #666;
        }
        
        .list-item:hover {
            background-color: #f5f5f5;
        }
    </style>
</head>
<body>
    <h1 style="text-align: center; margin: 20px 0;">原生JavaScript虛擬列表</h1>
    <div id="virtualList" class="list-container">
        <div class="list-phantom"></div>
        <div class="list-content"></div>
    </div>
    <script>
        class VirtualList {
            constructor(options) {
                this.container = options.container;
                this.data = options.data || [];
                this.itemHeight = options.itemHeight || 50;
                this.bufferSize = options.bufferSize || 5;
                
                this.phantom = this.container.querySelector('.list-phantom');
                this.content = this.container.querySelector('.list-content');
                
                this.startIndex = 0;
                this.endIndex = 0;
                this.scrollTop = 0;
                
                this.init();
            }
            
            init() {
                // 設置占位容器的高度
                this.phantom.style.height = this.data.length * this.itemHeight + 'px';
                
                // 監聽滾動事件
                this.container.addEventListener('scroll', this.handleScroll.bind(this));
                
                // 初始渲染
                this.updateVisibleItems();
            }
            
            handleScroll() {
                // 獲取當前滾動位置
                this.scrollTop = this.container.scrollTop;
                
                // 更新可見項
                this.updateVisibleItems();
            }
            
            updateVisibleItems() {
                // 計算開始和結束索引
                this.startIndex = Math.floor(this.scrollTop / this.itemHeight);
                this.endIndex = this.startIndex + Math.ceil(this.container.clientHeight / this.itemHeight);
                
                // 添加緩沖區
                this.startIndex = Math.max(0, this.startIndex - this.bufferSize);
                this.endIndex = Math.min(this.data.length, this.endIndex + this.bufferSize);
                
                // 計算偏移量
                const offsetY = this.startIndex * this.itemHeight;
                
                // 設置內容容器的偏移
                this.content.style.transform = `translateY(${offsetY}px)`;
                
                // 渲染可見項
                this.renderItems();
            }
            
            renderItems() {
                // 清空內容容器
                this.content.innerHTML = '';
                
                // 渲染可見項
                for (let i = this.startIndex; i < this.endIndex; i++) {
                    const item = document.createElement('div');
                    item.className = 'list-item';
                    item.innerHTML = this.renderItemContent(this.data[i], i);
                    item.style.height = this.itemHeight + 'px';
                    this.content.appendChild(item);
                }
            }
            
            renderItemContent(item, index) {
                return `<div>索引: ${index}, 內容: ${item}</div>`;
            }
        }
        
        // 生成測試數據
        const data = Array.from({ length: 10000 }, (_, i) => `列表項 ${i + 1}`);
        
        // 初始化虛擬列表
        const virtualList = new VirtualList({
            container: document.getElementById('virtualList'),
            data: data,
            itemHeight: 50,
            bufferSize: 10
        });
    </script>
</body>
</html>

 

5.最后總結

為什么滾動到指定位置后會將對應區域數據渲染?

1.監聽滾動事件

2.滾動觸發數據更新方法

3.根據滾動距離計算當前數據索引

4.根據可視區域計算要渲染數據項

5.渲染數據

6.定位內容

轉自https://www.cnblogs.com/FatTiger4399/p/18780549


該文章在 2025/3/20 9:22:34 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved