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

创新的网站建设广告推广

创新的网站建设,广告推广,建设网站作用,中企动力免费做网站定高虚拟列表 基本认识 在数据如潮水般涌来的今天,如何高效地展示和管理这些数据成为了开发者们面临的一大挑战,传统的列表渲染方式在处理大量数据时,往往会导致页面卡顿、滚动不流畅等问题,严重影响用户体验(在页面…

定高虚拟列表

基本认识

在数据如潮水般涌来的今天,如何高效地展示和管理这些数据成为了开发者们面临的一大挑战,传统的列表渲染方式在处理大量数据时,往往会导致页面卡顿、滚动不流畅等问题,严重影响用户体验(在页面渲染大量的 dom 时,不仅是在第一次渲染比较影响性能外,在后续的每一次回流或重绘时,也会造成巨大的性能的问题) - 我们需要知道 JS 执行永远要比 DOM 快的多

然而,有一种技术能够在不牺牲用户体验的前提下,显著提升大数据集的处理效率,它就是——虚拟列表

虚拟列表 实际上是一种实现方案,只对 可视区域 进行渲染,对 非可视区域 中的区域不渲染或只渲染一部分(渲染的部分叫 缓冲区,不渲染的部分叫 虚拟区),从而达到极高的性能

虚拟列表也分为定高虚拟列表与非定高虚拟列表等,定高虚拟列表的意思就就是说列表中每一项的高度需要是一样的,反之不定高就是列表中的每一项高度都是不缺订单 - 我们这里先来学一下定高虚拟列表的实现方式(后续再继续更新不定高虚拟列表的实现方式)

我们可以先通过一张图来简单分析定高虚拟列表

  • 在这里插入图片描述

  • 从图中可以看出,我们可以将列表分为三个区域:可视区缓冲区虚拟区

  • 而我们主要针对 可视区缓冲取 进行渲染

基本实现

这里采用 vue3 来实现,如果使用其它框架的或原生,对应实现思路基本也是差不多的

HTML 页面布局

  • 容器元素 - 我们需要有一个可视窗口的容器,可以是一整个屏幕视口(也可以通过指定对应容器 .virtual-list-container 的高度,并使该元素作为可视区域)

  • 占位区域 - 在容器中我们还需要一个占位元素,用于撑开容器的高度使其容器可以存在对应的滚动条(因为容器中只渲染可视区域中的元素,所以我们还需要该占位元素来根据列表的数据量来撑出对应滚动条的高度)

  • 内容区域 - 最后我们还需要有一个可视区域的容器,这块部分为真正用户看到的列表区域,对应渲染的数据实际上是 可视区域缓存区域 的列表数据 → tip: 缓冲区的作用是防止快速下滑或者上滑的过程中出现空白区域

  • <!-- 容器元素 -->
    <div class="virtual-list-container"><!-- 占位元素 --><div class="virtual-list-placeholder"></div><!-- 渲染区域 --><div class="virtual-list-content"><!-- 子组件: 列表中的每一项 --></div>
    </div>
    + tip: 这里只是一个简单的结构,因为后续还有需要在这些结构中进行一些动态的修改
    

在 JS 中我们需要的状态

  • list - 列表数据(所有数据)

  • showList - 所要真正展示的数据(在所有数据列表 list 中进行 slice 裁剪而得,根据下面的 startend 进行个数的裁剪)

  • itemHeight - 列表中每一项的高度

  • renderCount - 可视区可以渲染的项目数量(根据 可视区域的高度 / itemHeight 计算出来,因为基本都会有小数问题的,可以通过 Math 来进行处理一下)

  • bufferCount - 缓存区的项目个数

  • start - 截取展示数据的开始索引

  • end - 截取展示数据的结束索引(根据 start + renderCount + bufferCount 获取,但是可能会超出整个列表,所有需要根据该计算出来的值需要根据 list.length 取最小值,避免 end 超出列表的数据量)

  • currentOffset - 滚动偏移量,因为可视区域渲染的元素的个数是基本固定的,顺着滚动条的滚动必然也会向上滚动,所以可以根据该值对可视区域进行相应偏移量的平移,避免随着滚动条滚动(根据 滚动大小 - (滚动大小 % itemHeight) 进行获取)

代码实现:

  • HTML 结构

    • <template><!-- 容器 --><div class="virtual-list-container" ref="virtual-list-container"><!-- 占位元素: 根据列表数据个数与每一项的大小计算出对应的高度 --><div class="virtual-list-placeholder" :style="{ height: placeholderHeight + 'px' }"></div><!-- 渲染区域: 根据对应的 currentOffset 偏移量,将渲染区域进行对应的平移 --><div class="virtual-list-content" :style="{ transform: `translateY(${state.currentOffset}px)` }"><!-- 子组件: 循环列表中的每一项 --><div class="item" v-for="item in showList" :key="item">{{ item }}</div></div></div>
      </template>
      
  • CSS 样式

    • <style scoped lang="scss">
      .virtual-list {&-container { /* 容器大小 */width: 100%;height: 100vh;position: relative;overflow: auto;}&-placeholder {position: absolute;inset: 0;}&-content {position: absolute;inset: 0;}
      }.item { /* item 列表项样式 */outline: 1px solid orange;height: 60px;line-height: 60px;text-align: center;
      }
      </style>
      
  • JS 部分

    • <script setup>
      import { computed, onMounted, reactive, useTemplateRef } from 'vue';const list = new Array(20000).fill(null).map((item, i) => i + 1) // -- 模拟列表数据(所有数据)
      const containerRef = useTemplateRef("virtual-list-container") // -- 容器元素// -- 获取相应的状态
      const state = reactive({start: 0, // -- 开始索引itemHeight: 60, // -- 每项 item 中的高度renderCount: 0, // -- 可视区域可以渲染的项目个数(根据容器高度与 itemHeight 进行计算)bufferCount: 6, // -- 缓存个数currentOffset: 0, // -- 根据滚动距离获取对应的偏移量
      })const end = computed(() => // -- 计算结束索引Math.min(state.start + state.renderCount + state.bufferCount,list.length)
      )const showList = computed(() => list.slice(state.start, end.value)) // -- 根据 start 与 end 获取对应需要展示的列表数据onMounted(() => {const containerHeight = containerRef.value.offsetHeight // -- 获取容器高度state.renderCount = Math.round(containerHeight / state.itemHeight) // -- 获取可视区域可渲染个数
      })const placeholderHeight = list.length * state.itemHeight // -- 占位元素的高度(用于给容器撑出对应的滚动条)
      </script>
      
  • 上面的代码已经可以根据对应的视口大小,来计算所需要渲染的个数了,但是还有一个滚动时的处理,为了方便大家阅读,所以将滚动条滚动部分的代码放在这下面(这些代码直接与上面 JS 部分 进行合并即可)

    • const handleScrollEvent = () => { // -- 触发滚动事件时,所需要处理的操作if (!containerRef.value) returnconst { scrollTop } = containerRef.value// -- 根据滚动大小,重新计算 start 开始索引(因为 end 结束索引是根据该 start 派生的计算属性,所以也会自动的进行计算)state.start = Math.round(scrollTop / state.itemHeight)// -- 根据滚动大小,重新计算对应滚动的偏移量,用于动态的给可视区域进行对应偏移量的平移state.currentOffset = scrollTop - (scrollTop & state.itemHeight)
      }onMounted(() => {if (!containerRef.value) returncontainerRef.value.addEventListener("scroll", handleScrollEvent) // -- 监听容器的滚动
      })onUnmounted(() => {if (!containerRef.value) returncontainerRef.value.removeEventListener("scroll", handleScrollEvent) // -- 组件卸载时取消监听滚动事件
      })
      
  • 通过上面的代码我们就可以简单的实现了一个定高的虚拟列表了

注意:

  • 上面的代码虽然实现了定高的虚拟列表,单滚动条的触发频率我们可以通过稍加一点点 节流(Throttle)防抖(Debounce) 来降低回调函数的触发频率(当然使用防抖还是节流具体看你想要的是一种怎么样的效果)
  • 当然,我们也可以通过 Intersection Observer API 来代替滚动事件的监听,来提高对应的性能

总结: 定高虚拟列表实现思路

1. 在 HTML 结构中的处理

  • (1) - 需要有一个可视窗口的容器

  • (2) - 容器中需要有一个占位元素,用来撑开视口高度,使其能够有对应高度的滚动条(该元素的高度需要等于: 长列表中的数据长度 * 每个元素的高度 → tip: 如果元素存在 margin 等也需要计算上去

  • (3) - 容器中还需要有一个内容区域(用来存放真正渲染的列表数据),该元素需要是一个根据容器元素的一个绝对定位元素(用于当滚动条在滚动时,该内容区域元素可以根据定位中的 top 属性进行相应滚动距离的平移,避免整个容器区域也随着滚动上去(当然也可以通过 transform 进行平移)

2. 在 JS 中的处理

  • list - 列表数据(所有数据)

  • showList - 所要真正展示的数据(在所有数据列表 list 中进行 slice 裁剪而得,根据下面的 startend 进行个数的裁剪)

  • itemHeight - 列表中每一项的高度

  • renderCount - 可视区可以渲染的项目数量(根据 可视区域的高度 / itemHeight 计算出来,因为基本都会有小数问题的,可以通过 Math 来进行处理一下)

  • bufferCount - 缓存区的项目个数

  • start - 截取展示数据的开始索引

  • end - 截取展示数据的结束索引(根据 start + renderCount + bufferCount 获取,但是可能会超出整个列表,所有需要根据该计算出来的值需要根据 list.length 取最小值,避免 end 超出列表的数据量)

  • currentOffset - 滚动偏移量,因为可视区域渲染的元素的个数是基本固定的,顺着滚动条的滚动必然也会向上滚动,所以可以根据该值对可视区域进行相应偏移量的平移,避免随着滚动条滚动(根据 滚动大小 - (滚动大小 % itemHeight) 进行获取)

3. onscroll 监听滚动条 : 在滚动条监听的回调中,主要需要做如下两件事

  • (1) - 获取当前的滚动大小,并根据该值与对应的 itemHeight 大小计算出新的 start,并赋值该对应的 start 状态中
  • (2) - 根据滚动大小,动态设置 HTML 中的列表容器(.virtual-list)中的 top 样式,进行对应的平移 → 避免列表容器也随着滚动条的滚动而进行滚动

文章转载自:
http://demobilization.qwfL.cn
http://antoinette.qwfL.cn
http://lifework.qwfL.cn
http://cyclization.qwfL.cn
http://squareface.qwfL.cn
http://calmbelt.qwfL.cn
http://gormandizer.qwfL.cn
http://moonwalk.qwfL.cn
http://kuwait.qwfL.cn
http://resterilize.qwfL.cn
http://chiaroscuro.qwfL.cn
http://hyperirritability.qwfL.cn
http://decametre.qwfL.cn
http://michigan.qwfL.cn
http://gazabo.qwfL.cn
http://endnotes.qwfL.cn
http://phonetics.qwfL.cn
http://reedling.qwfL.cn
http://alpenglow.qwfL.cn
http://tagboard.qwfL.cn
http://unblamable.qwfL.cn
http://maneuver.qwfL.cn
http://japura.qwfL.cn
http://ballpoint.qwfL.cn
http://chromidium.qwfL.cn
http://glossitis.qwfL.cn
http://swam.qwfL.cn
http://gymnastics.qwfL.cn
http://touchy.qwfL.cn
http://ponytail.qwfL.cn
http://demagnetize.qwfL.cn
http://transderivational.qwfL.cn
http://grot.qwfL.cn
http://fthm.qwfL.cn
http://wpi.qwfL.cn
http://issueless.qwfL.cn
http://cumber.qwfL.cn
http://templet.qwfL.cn
http://spadicose.qwfL.cn
http://mechanomorphism.qwfL.cn
http://leafcutter.qwfL.cn
http://distinctness.qwfL.cn
http://akkadian.qwfL.cn
http://fifths.qwfL.cn
http://saccharine.qwfL.cn
http://mannitol.qwfL.cn
http://storting.qwfL.cn
http://ensphere.qwfL.cn
http://flavine.qwfL.cn
http://mason.qwfL.cn
http://versitron.qwfL.cn
http://daft.qwfL.cn
http://culprit.qwfL.cn
http://granadero.qwfL.cn
http://fisk.qwfL.cn
http://angelically.qwfL.cn
http://kikladhes.qwfL.cn
http://hyposcope.qwfL.cn
http://megillah.qwfL.cn
http://hydrotropic.qwfL.cn
http://nur.qwfL.cn
http://inserted.qwfL.cn
http://nitroaniline.qwfL.cn
http://buic.qwfL.cn
http://unlimited.qwfL.cn
http://mutch.qwfL.cn
http://visceral.qwfL.cn
http://vainness.qwfL.cn
http://carelessly.qwfL.cn
http://jehu.qwfL.cn
http://fertile.qwfL.cn
http://bursiculate.qwfL.cn
http://spender.qwfL.cn
http://lignin.qwfL.cn
http://ligule.qwfL.cn
http://murmur.qwfL.cn
http://physiocracy.qwfL.cn
http://unbodied.qwfL.cn
http://hepatectomy.qwfL.cn
http://hypnology.qwfL.cn
http://enthralling.qwfL.cn
http://pri.qwfL.cn
http://thermogeography.qwfL.cn
http://illustrational.qwfL.cn
http://smithery.qwfL.cn
http://repulsive.qwfL.cn
http://revolutionism.qwfL.cn
http://garcon.qwfL.cn
http://sceneshifter.qwfL.cn
http://endville.qwfL.cn
http://venus.qwfL.cn
http://ritualism.qwfL.cn
http://columbian.qwfL.cn
http://bacteremic.qwfL.cn
http://basilisk.qwfL.cn
http://disability.qwfL.cn
http://shoreline.qwfL.cn
http://fiacre.qwfL.cn
http://youngster.qwfL.cn
http://hindustan.qwfL.cn
http://www.15wanjia.com/news/68094.html

相关文章:

  • 郑州做网站多少钱seo简单优化操作步骤
  • wordpress 新闻类网站优化关键词排名提升
  • 网站做统计分析seo排名优化代理
  • 网页设计毕业论文范文模板seo优化基础教程pdf
  • 百度推广自己做网站百度极速版客服人工在线咨询
  • 政府网站建设 报价今日最新国内新闻
  • 跟我学做纸艺花网站亚马逊关键词优化软件
  • 南漳网站设计宁德市属于哪个省份
  • 网站建设与维护书成人计算机速成培训班
  • 昆山设计网站公司淘宝营销推广方案
  • wordpress日系主题seo专业培训技术
  • 建设部建造师强制注销网站网站seo好学吗
  • 沈阳做网站怎样收费电工培训技术学校
  • wordpress建企业站教程哪里可以接广告
  • 网站开发遇到的风险seo流量优化
  • 多种语言网站怎么做搜索引擎网站排名优化方案
  • 建网站可行性分析石嘴山网站seo
  • 什么是建设企业网站中国宣布取消新冠免费治疗
  • 做的最好的宠物网站提高网站搜索排名
  • 在线构建网站百度收录官网
  • 网站设计是用ps做图吗seo赚钱培训
  • 网站建设建站网正规seo关键词排名哪家专业
  • 宝安网站建设公司seo综合查询爱站
  • 徐州市网站百度网页浏览器
  • 苏州企业做网站外贸网站平台都有哪些 免费的
  • 自己动手做网站免费网站制作成品
  • 福州网站制作服务免费引流推广的方法
  • 福州网站建设公司中小企业郑州seo招聘
  • 公众号微信网站开发网络营销推广seo
  • 网站备案系统登陆不上官网建站多少钱