js实现前端无限滚动中的虚拟列表效果(只渲染可视区域,dom元素可复用)

您所在的位置:网站首页 react虚拟列表无限循环滚动数据 js实现前端无限滚动中的虚拟列表效果(只渲染可视区域,dom元素可复用)

js实现前端无限滚动中的虚拟列表效果(只渲染可视区域,dom元素可复用)

2024-07-13 00:35| 来源: 网络整理| 查看: 265

先看效果

不加防抖节流。 在这里插入图片描述 加防抖节流 在这里插入图片描述

提示

加防抖节流 可以节省性能,但滑动过快会出现闪烁现象。请根据需求自行调整触发时间。原理通过代码可看出!

限制:该代码处理方式由于html 元素高度存在最大值,且不同浏览器以及不同浏览器版本支持的html 元素高度最大值不一样,当数据列表理论生成的高度大于html元素高度最大值时,生成的滚动区域只有html元素高度最大值那部分,剩下部分无法显示出来。

代码 不加防抖节流 无限滚动中的虚拟列表(只渲染可视区域,dom元素可复用) 无限滚动中的虚拟列表(只渲染可视区域,dom元素可复用) .container { height: 600px; overflow: auto; } .item { min-height: 60px; border-bottom: 1px solid #cccccc; border-top: 1px solid #cccccc; width: 100%; text-align: center; background-color: darkgray; /* padding: 30px 0; box-sizing: border-box; */ } 0 1 2 3 4 5 6 7 8 9 var item = document.querySelector('.viewArea .item'); //需要渲染的单个列表元素 var container = document.querySelector('.container'); //可视区域元素 console.log(item); var start = 0; // 开始位置 var pageSize = 10; // 每页展示的数据 var total = 100000; //数据总长度 // var itemHeight = 61; // 每个item的高度 var itemStyle = getComputedStyle(item); // 获取元素最终样式 var itemHeight = Number(itemStyle.height.split('px')[0]) + Number(itemStyle.borderTopWidth.split('px')[0]) + Number(itemStyle.borderBottomWidth.split('px')[0]); // 每个item的高度 console.log('itemHeight', itemHeight); // 设置数据列表的总高度 document.querySelector('.container .content').style.height = itemHeight * total + 'px'; updateDom(start, pageSize, itemHeight, 0); //更新渲染列表函数 function updateDom(start, pageSize, itemHeight, height) { document.querySelector('.container .content .viewArea').style.transform = 'translateY(' + height + 'px)'; let all = document.querySelectorAll(' .viewArea .item'); // 获取所有渲染列表 for (var i = start, itemIndex = 0, len = start + pageSize; i { var currentScrollTop = container.scrollTop; var fixedScrollTop = currentScrollTop - currentScrollTop % itemHeight; var start = Math.floor(currentScrollTop / itemHeight); if (lastStart !== start) { lastStart = start; updateDom(start, pageSize, itemHeight, fixedScrollTop); } } } // // 防抖和节流 // function throttle(fn, delay, atleast) { // let timer = null; // let rAFtimer = null; // let previous = 0; // return function () { // let now = Date.now(); // if (now - previous > atleast) { // console.log('now - previous > atleast'); // fn(); // previous = now; // } else { // if (delay > 20) { // console.log('delay > 20'); // clearTimeout(timer); // timer = setTimeout(function () { // fn(); // previous = 0; // }, delay); // } else { // console.log('delay < 20'); // cancelAnimationFrame(rAFtimer); // rAFtimer = requestAnimationFrame(function () { // requestIdleCallback(fn); // }); // } // } // } // } // document.querySelector('.container').addEventListener('scroll', throttle(handleScroller(), 16, 500), false); document.querySelector('.container').addEventListener('scroll', handleScroller(), false); 加防抖节流 无限滚动中的虚拟列表(只渲染可视区域,dom元素可复用) 无限滚动中的虚拟列表-防抖和节流(只渲染可视区域,dom元素可复用) .container { height: 600px; overflow: auto; } .item { min-height: 60px; border-bottom: 1px solid #cccccc; border-top: 1px solid #cccccc; width: 100%; text-align: center; background-color: darkgray; /* padding: 30px 0; box-sizing: border-box; */ } 0 1 2 3 4 5 6 7 8 9 var item = document.querySelector('.viewArea .item'); var container = document.querySelector('.container'); console.log(item); var start = 0; // 开始位置 var pageSize = 10; // 每页展示的数据 var total = 100000; //数据总长度 // var itemHeight = 61; // 每个item的高度 var itemStyle = getComputedStyle(item); var itemHeight = Number(itemStyle.height.split('px')[0]) + Number(itemStyle.borderTopWidth.split('px')[0]) + Number(itemStyle.borderBottomWidth.split('px')[0]); // 每个item的高度 console.log('itemHeight', itemHeight); // 设置数据列表的总高度 document.querySelector('.container .content').style.height = itemHeight * total + 'px'; updateDom(start, pageSize, itemHeight, 0); function updateDom(start, pageSize, itemHeight, height) { document.querySelector('.container .content .viewArea').style.transform = 'translateY(' + height + 'px)'; let all = document.querySelectorAll(' .viewArea .item'); for (var i = start, itemIndex = 0, len = start + pageSize; i { var currentScrollTop = container.scrollTop; var fixedScrollTop = currentScrollTop - currentScrollTop % itemHeight; var start = Math.floor(currentScrollTop / itemHeight); if (lastStart !== start) { lastStart = start; updateDom(start, pageSize, itemHeight, fixedScrollTop); } } } // 防抖和节流 function throttle(fn, delay, atleast) { let timer = null; let rAFtimer = null; let previous = 0; return function () { let now = Date.now(); if (now - previous > atleast) { console.log('now - previous > atleast'); fn(); previous = now; } else { if (delay > 20) { console.log('delay > 20'); clearTimeout(timer); timer = setTimeout(function () { fn(); previous = 0; }, delay); } else { console.log('delay < 20'); cancelAnimationFrame(rAFtimer); rAFtimer = requestAnimationFrame(function () { requestIdleCallback(fn); }); } } } } document.querySelector('.container').addEventListener('scroll', throttle(handleScroller(), 16, 500), false); // document.querySelector('.container').addEventListener('scroll', handleScroller(), false);


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3