当前位置: 首页 > news >正文

建设有访问量的网站西双版纳傣族自治州有几个县

建设有访问量的网站,西双版纳傣族自治州有几个县,最常用的网页制作软件,免费下载的网站用原生JS实现虚拟列表 介绍 最近在开发需求的时候#xff0c;有用到 Antd 的虚拟列表组件 rc-virtual-list #xff0c;粗略地看了一下源码#xff0c;于是萌生了自己写一个虚拟列表的想法。当一个列表需要渲染大量数据的时候是非常耗时的#xff0c;而且在列表滚动的过程…用原生JS实现虚拟列表 介绍 最近在开发需求的时候有用到 Antd 的虚拟列表组件 rc-virtual-list 粗略地看了一下源码于是萌生了自己写一个虚拟列表的想法。当一个列表需要渲染大量数据的时候是非常耗时的而且在列表滚动的过程中会出现卡顿的现象。即使用上懒加载解决了列表初始化时渲染过慢的问题但是每次拉取下一页数据的时候都会造成列表的重新渲染。随着拉取的数据越来越多列表渲染时间长、卡顿的问题依然存在。这个时候虚拟列表就派上用场了。虚拟列表的实现原理简单来说就是列表并不会把所有的数据都渲染出来而是通过监听滚动事件然后实时计算当前是哪几条数据显示在页面上然后只渲染用户可以看见的这几条数据。在网上找了张图可以说明的更生动些[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vbz6hBM5-1684195418798)(C:\Users\quyanliang\AppData\Roaming\Typora\typora-user-images\1684195219996.png)] 定高虚拟列表 实现虚拟列表需要两层的div style.list-container {overflow: auto;border: 1px solid black;height: 500px;} /stylebody!-- 外部容器用来固定列表容器的高度同时生成滚动条 --div classlist-container!-- 内部容器用来装元素高度是所有元素高度的和 --div classlist-container-inner/div/divÏ /body外层的div用来固定高度也就是图上展示的B区域。内层的div用来装列表元素也就是图上展示的A区域。给外层的div设置 overflow: auto 这样当列表元素数量超过B区域的高度时就会出现滚动条。 接下来我们需要监听外层div的滚动事件实时计算出显示在可视区域上的第一个元素的坐标 startIndex 和 最后一个元素的坐标 endIndex。假设列表每个元素的高度都是60px那么 startIndex 就等于外层 div 顶部卷起来的长度除以列表元素的高度而 endIndex 就等于 startIndex 可视区域能展示的元素个数 const itemHeight 60 const height 500 const startIndex Math.floor(outerContainer.scrollTop / itemHeight) const endIndex startIndex Math.ceil(height / itemHeight)然后用 startIndex 和 endIndex 去截取数据并渲染在内层 div 上 const viewData data.slice(startIndex, endIndex 1) const innerContainer document.querySelector(.list-container-inner) innerContainer.innerHTML for(let i 0; i viewData.length; i) {const item document.createElement(div)item.innerHTML viewData[i]innerContainer.appendChild(item) }最后一步虽然我们只需要渲染在可视区域上的元素但是我们还需要给内层的 div 设置 padding-top 和 padding-bottom 替代那些不需要渲染的元素。由此保证虚拟列表是可以滚动的而且滚动条位置和列表元素位置是相对应的。 padding-top 等于 startIndex 之前的元素高度和 padding-bottom 等于 endIndex 之后的元素高度和 const paddingTop startIndex * itemHeight const paddingBottom (data.length - endIndex) * itemHeight innerContainer.setAttribute(style, padding-top: ${paddingTop}px; padding-bottom: ${paddingBottom}px)完整代码 style.list-container {overflow: auto;border: 1px solid black;height: 500px;} /stylebody!-- 外部容器用来固定列表容器的高度同时生成滚动条 --div classlist-container!-- 内部容器用来装元素高度是所有元素高度的和 --div classlist-container-inner/div/divscript/** --------- 一些基本变量 -------- */const itemHeight 60const height 500/** --------- 生成数据 -------- */const initData () {const data []for(let i 0; i 15; i) {data.push({content: 内容:${i}, height: itemHeight, color: i % 2 ? red : yellow})}return data}const data initData()const contentHeight itemHeight * data.lengthconst outerContainer document.querySelector(.list-container)const scrollCallback () {// 获取当前要渲染的元素的坐标const scrollTop Math.max(outerContainer.scrollTop, 0)const startIndex Math.floor(scrollTop / itemHeight)const endIndex startIndex Math.ceil(height / itemHeight)const innerContainer document.querySelector(.list-container-inner)// 从data取出要渲染的元素并渲染到容器中const viewData data.slice(startIndex, endIndex 1)innerContainer.innerHTML for(let i 0; i viewData.length; i) {const item document.createElement(div)const itemData viewData[i]item.innerHTML itemData.contentitem.setAttribute(style, height: ${itemData.height}px; background: ${itemData.color})innerContainer.appendChild(item)}// 未渲染的元素由padding-top和padding-bottom代替保证滚动条位置正确const paddingTop startIndex * itemHeightconst paddingBottom (data.length - endIndex) * itemHeightinnerContainer.setAttribute(style, padding-top: ${paddingTop}px; padding-bottom: ${paddingBottom}px)}// 首屏渲染scrollCallback()// 监听外部容器的滚动事件outerContainer.addEventListener(scroll, scrollCallback)/script /body不定高虚拟列表 上面实现的是元素高度固定的虚拟列表对于元素高度不固定的情况虚拟列表实现起来会更复杂一些。 因为我们事先不知道元素的高度所以在监听滚动事件的过程中需要遍历一遍列表获取每个元素的高度由此算出 startIndex 、 endIndex 等数据。不过在第一次渲染之前因为元素没有渲染出来我们拿不到元素的真实高度。所以这时候需要给元素一个最小高度 itemHeight 通过 itemHeight 来计算 startIndex 和 endIndex由此保证第一次渲染出来的元素能占满整个可视区域。 另外当元素渲染出来以后我们用一个字典去记录每个元素的真实高度供下次滚动事件触发时 startIndex 和 endIndex 的计算。 startIndex 的算法是在遍历列表元素的过程中逐步累加当前元素的高度得到 contentHeight 当第一次出现 contentHeight 大于容器顶部卷起来的长度的时候说明当前元素是列表可视区域的第一个元素记为 startIndex。 endIndex 的算法是当第一次出现 contentHeight 大于 容器顶部卷起来的长度 容器高度 的时候说明当前元素是列表可视区域的最后一个元素记为 endIndex 。 完整代码 style.list-container {overflow: auto;border: 1px solid black;height: 500px;} /stylebody!-- 外部容器用来固定列表容器的高度同时生成滚动条 --div classlist-container!-- 内部容器用来装元素高度是所有元素高度的和 --div classlist-container-inner/div/divscript/** --------- 一些基本变量 -------- */const itemHeight 60const height 500/** --------- 生成数据 -------- */const getRandomHeight () {// 返回 [60, 150] 之间的随机数return Math.floor(Math.random() * (150 - itemHeight 1) itemHeight)}const initData () {const data []for(let i 0; i 15; i) {data.push({content: 内容:${i}, height: getRandomHeight(), color: i % 2 ? red : yellow})}return data}const data initData()const cacheHeightMap {}const outerContainer document.querySelector(.list-container)const scrollCallback () {let contentHeight 0let paddingTop 0let upperHeight 0let startIndexlet endIndexconst innerContainer document.querySelector(.list-container-inner)const scrollTop Math.max(outerContainer.scrollTop, 0)// 遍历所有的元素获取当前元素的高度、列表总高度、startIndex、endIndexfor(let i 0; i data.length; i) {// 初始化的时候因为元素还没有渲染无法获取元素的高度// 所以用元素的最小高度itemHeight来进行计算保证渲染的元素个数能占满列表const cacheHeight cacheHeightMap[i]const usedHeight cacheHeight undefined ? itemHeight : cacheHeightcontentHeight usedHeightif (contentHeight scrollTop startIndex undefined) {startIndex ipaddingTop contentHeight - usedHeight}if (contentHeight scrollTop height endIndex undefined) {endIndex iupperHeight contentHeight}}// 应对列表所有元素没有占满整个容器的情况if (endIndex undefined) {endIndex data.length - 1upperHeight contentHeight}// 未渲染的元素的高度由padding-top和padding-bottom代替保证滚动条位置正确// 这里如果把设置pading的操作放在渲染元素之后部分浏览器滚动到最后一个元素时会有问题const paddingBottom contentHeight - upperHeightinnerContainer.setAttribute(style, padding-top: ${paddingTop}px; padding-bottom: ${paddingBottom}px)// 从data取出要渲染的元素并渲染到容器中const viewData data.slice(startIndex, endIndex 1)innerContainer.innerHTML const fragment document.createDocumentFragment()for(let i 0; i viewData.length; i) {const item document.createElement(div)const itemData viewData[i]item.innerHTML itemData.contentitem.setAttribute(style, height: ${itemData.height}px; background: ${itemData.color})fragment.appendChild(item)}innerContainer.appendChild(fragment)// 存储已经渲染出来的元素的高度供后面使用const children innerContainer.childrenlet flag startIndexfor(const child of children) {cacheHeightMap[flag] child.offsetHeightflag}}// 首屏渲染scrollCallback()// 监听外部容器的滚动事件outerContainer.addEventListener(scroll, scrollCallback)/script /body
http://www.hkea.cn/news/14440045/

相关文章:

  • 月编程做网站免费域名映射
  • 门户网站开发要求flash可以用来制作网页吗
  • 建设网站需要哪些资质php做网站完整视频
  • 深圳建站公司设计深业集团wordpress大学模板2.7
  • wordpress怎么使用江门网站快速排名优化
  • 在哪注册网站能上传文件的网站
  • 做设计用到的网站北京营销型网站开发
  • 商标网站建设展览展示设计有限公司
  • 网站后台更换首页图片wordpress导购插件
  • 山东鲁为建设集团网站菏泽网站建设推广价格
  • discuz修改网站底部深圳市中医院
  • 网站建设需要注意那些点建设银行网站怎么登录密码忘了怎么办
  • 马鞍山网站建设价格网站导航提交入口大全
  • 福州网站推广优化航空港建设局网站
  • 图标设计网站做网站运用的技术
  • 济源网站建设公司摄影作品网站推荐
  • 门户首页网站建设方案小票在线生成小程序
  • 冠县做网站专业官方网站建设
  • 工信部查询网站备案吉林省建设安全厅官方网站
  • 企业网站推广17手机如何创建公众号
  • 网站后台管理系统很慢女的男的做那个视频网站
  • 社区问答网站开发东莞 网站建设
  • 西安网站建设熊掌浏览器怎么连接网站的
  • 带做网站更改网站的布局
  • 宁波建设信息网站对网站外部的搜索引擎优化
  • 博客自助建站厂里拿货开小加工厂
  • 今天的国内新闻seo专业培训需要多久
  • 网站弹出文字网站推广基本预算
  • php mysql开发网站开发长沙网络营销公司排名
  • 免费微信网站模板下载工具视频网站文案