原生JS實現虛擬列表(不使用Vue,React等前端框架)
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
1. 什么是虛擬列表虛擬列表(Virtual List)是一種優化長列表渲染性能的技術。當我們需要展示成千上萬條數據時,如果一次性將所有數據渲染到DOM中,會導致頁面卡頓甚至崩潰。虛擬列表的核心思想是:只渲染可視區域內的數據,而不是渲染所有數據
2. 使用場景虛擬列表適用于以下場景:
(我覺得實際場景中,分頁會用到更多,用戶要看的數據,永遠只是一小部分,就那么幾條,找不到就用搜索 但總要學學)
3. 虛擬列表原理一句話:
要看了,再渲染
對,就這么簡單,下面,進行分步
這里幾個難點:
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 編輯過 |
關鍵字查詢
相關文章
正在查詢... |