超碰人人人人人,色婷婷综合久久久久中文一区二区,国产-第1页-浮力影院,欧美老妇另类久久久久久

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

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

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

1. 什么是虛擬列表

虛擬列表(Virtual List)是一種優(yōu)化長(zhǎng)列表渲染性能的技術(shù)。當(dāng)我們需要展示成千上萬(wàn)條數(shù)據(jù)時(shí),如果一次性將所有數(shù)據(jù)渲染到DOM中,會(huì)導(dǎo)致頁(yè)面卡頓甚至崩潰。虛擬列表的核心思想是:只渲染可視區(qū)域內(nèi)的數(shù)據(jù),而不是渲染所有數(shù)據(jù)

 

2. 使用場(chǎng)景

虛擬列表適用于以下場(chǎng)景:

  • 大數(shù)據(jù)量展示:如聊天記錄、新聞列表、商品列表等需要展示大量數(shù)據(jù)的場(chǎng)景
  • 無(wú)限滾動(dòng):需要支持用戶持續(xù)滾動(dòng)加載更多內(nèi)容的場(chǎng)景
  • 性能敏感:在低性能設(shè)備上運(yùn)行的應(yīng)用,需要盡可能減少DOM操作
  • 實(shí)時(shí)數(shù)據(jù)更新:頻繁更新的數(shù)據(jù)列表,如股票行情、實(shí)時(shí)監(jiān)控?cái)?shù)據(jù)等

(我覺得實(shí)際場(chǎng)景中,分頁(yè)會(huì)用到更多,用戶要看的數(shù)據(jù),永遠(yuǎn)只是一小部分,就那么幾條,找不到就用搜索

但總要學(xué)學(xué))

 

3. 虛擬列表原理

一句話:

 

要看了,再渲染

 

對(duì),就這么簡(jiǎn)單,下面,進(jìn)行分步

  • 計(jì)算可視區(qū)域:確定用戶當(dāng)前可以看到的視口范圍
  • 計(jì)算可見項(xiàng):根據(jù)視口位置、每項(xiàng)高度,計(jì)算出當(dāng)前應(yīng)該顯示哪些數(shù)據(jù)項(xiàng)
  • 渲染可見項(xiàng):只渲染計(jì)算出的可見項(xiàng)到DOM中
  • 位置偏移:通過(guò)CSS定位,確保可見項(xiàng)在正確的位置顯示
  • 監(jiān)聽滾動(dòng):當(dāng)用戶滾動(dòng)時(shí),重新計(jì)算可見項(xiàng)并更新DOM

這里幾個(gè)難點(diǎn):
我怎么知道哪些數(shù)據(jù)進(jìn)入了可視區(qū)域?
答:監(jiān)聽滾動(dòng)距離,滾到哪,就從哪里開始

 

 

4. 實(shí)現(xiàn)虛擬列表

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虛擬列表實(shí)現(xiàn)</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() {
                // 設(shè)置占位容器的高度
                this.phantom.style.height = this.data.length * this.itemHeight + 'px';
                
                // 監(jiān)聽滾動(dòng)事件
                this.container.addEventListener('scroll', this.handleScroll.bind(this));
                
                // 初始渲染
                this.updateVisibleItems();
            }
            
            handleScroll() {
                // 獲取當(dāng)前滾動(dòng)位置
                this.scrollTop = this.container.scrollTop;
                
                // 更新可見項(xiàng)
                this.updateVisibleItems();
            }
            
            updateVisibleItems() {
                // 計(jì)算開始和結(jié)束索引
                this.startIndex = Math.floor(this.scrollTop / this.itemHeight);
                this.endIndex = this.startIndex + Math.ceil(this.container.clientHeight / this.itemHeight);
                
                // 添加緩沖區(qū)
                this.startIndex = Math.max(0, this.startIndex - this.bufferSize);
                this.endIndex = Math.min(this.data.length, this.endIndex + this.bufferSize);
                
                // 計(jì)算偏移量
                const offsetY = this.startIndex * this.itemHeight;
                
                // 設(shè)置內(nèi)容容器的偏移
                this.content.style.transform = `translateY(${offsetY}px)`;
                
                // 渲染可見項(xiàng)
                this.renderItems();
            }
            
            renderItems() {
                // 清空內(nèi)容容器
                this.content.innerHTML = '';
                
                // 渲染可見項(xiàng)
                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}, 內(nèi)容: ${item}</div>`;
            }
        }
        
        // 生成測(cè)試數(shù)據(jù)
        const data = Array.from({ length: 10000 }, (_, i) => `列表項(xiàng) ${i + 1}`);
        
        // 初始化虛擬列表
        const virtualList = new VirtualList({
            container: document.getElementById('virtualList'),
            data: data,
            itemHeight: 50,
            bufferSize: 10
        });
    </script>
</body>
</html>

 

5.最后總結(jié)

為什么滾動(dòng)到指定位置后會(huì)將對(duì)應(yīng)區(qū)域數(shù)據(jù)渲染?

1.監(jiān)聽滾動(dòng)事件

2.滾動(dòng)觸發(fā)數(shù)據(jù)更新方法

3.根據(jù)滾動(dòng)距離計(jì)算當(dāng)前數(shù)據(jù)索引

4.根據(jù)可視區(qū)域計(jì)算要渲染數(shù)據(jù)項(xiàng)

5.渲染數(shù)據(jù)

6.定位內(nèi)容

轉(zhuǎn)自https://www.cnblogs.com/FatTiger4399/p/18780549


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