【性能优化】在大批量数据下使用 HTML+CSS实现走马灯,防止页面卡顿

切换效果

页面结构变化

1.需求背景

项目首页存有一个小的轮播模块,保密原因大概只能这么展示,左侧图片右侧文字,后端一次性返回几百条数据(开发环境下,生产环境只会更多).无法使用分页解决,前端需要懒加载防止页面卡顿

写个小demo演示,如下

2.解决思路

获取到数据后,取第一条数据展示.切换时,这里以查看下一张为例演示.切换下一张时,动态创建一个dom元素,通过字符串的方式设置innerHtml,将下一张的dom元素插入父节点.

同时父元素的第一个子元素(初始展示第一条数据的dom元素)和新创建的展示下一条数据的dom元素同时向左偏移自身宽度,然后把切走的dom元素清除,实现切换效果,同时避免页面大量结构堆积

3.代码如下

仅做了'下一张'功能,其他请自行补充

html 复制代码
<template>
    <div class="container">
        <button @click="golast">上一张</button>
        <button @click="gonext">下一张</button>
        <div class="windows">
            <div class="scrollBox">
                <div class="scrollItem">
                    <div class="img">
                        <el-image :src="initialData.imgUrl"></el-image>
                    </div>
                    <div class="messBox">{{ initialData.mess }}</div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
export default {
  data () {
    return {
      localData: [
       { imgUrl: '../assets/xxx.png', mess: '11111' },
       { imgUrl: '../assets/xxx.png', mess: '22222' },
       { imgUrl: '../assets/xxx.png', mess: '33333' },
       { imgUrl: '../assets/xxx.png', mess: '44444' },
       { imgUrl: '../assets/xxx.png', mess: '55555' },
       { imgUrl: '../assets/xxx.png', mess: '66666' },
      ],
      initialData: '', // 初始展示数据
      nowIndex: 0// 当前展示数据的索引
    }
  },
  created () {
  },
  mounted () {
    this.initData()
  },
  computed: {
  },
  methods: {
    initData () {
      // 初始副职
      this.initialData = this.localData[this.nowIndex]
    },

    // 点击查看上一张
    golast () {
    },

    // 点击查看下一张
    gonext () {
      if (this.localData.length <= this.nowIndex + 1) return
      this.readyBox('next')

      const fatherDom = document.querySelector('.windows')
      const moveDistanceX = fatherDom.offsetWidth
      const domArr = fatherDom.querySelectorAll('.scrollBox')
	   // 这里判断.初始结构和动态创建的元素的初始位置不同,导致偏移时的数值是不同的
      if (!domArr[0].classList.contains('newScrollBox')) {
        domArr[0].style.transform = `translate(-${moveDistanceX}px,0px)`
      } else {
        domArr[0].style.transform = `translate(-${moveDistanceX * 2}px,0px)`
      }
      domArr[1].style.transform = `translateX(-${moveDistanceX}px)`
      this.nowIndex++
      // 移除上一个dom元素
      const timeId1 = setTimeout(() => {
        fatherDom.removeChild(domArr[0])
        clearTimeout(timeId1)
      }, 501)
    },

    // 为下一次切换准备dom元素
    readyBox (type) {
      // 信息展示列表无数据或只有一条数据时,不执行
      if (this.localData.length <= 1) return

      let nextShowData = ''// 上一张或下一张要展示的数据
      const fatherDom = document.querySelector('.windows')// 获取父元素
      const newDom = document.createElement('div')// 创建新元素
      // 设置新元素的样式
      newDom.className = 'scrollBox'
      newDom.classList.add('newScrollBox')
      newDom.style.width = '100%'
      newDom.style.height = '100%'
      newDom.style.position = 'absolute'
      newDom.style.transition = 'all 0.5s'

      // 上一张
      if (type === 'last') {
        // 判断当前展示列表是否合法
        if (this.nowIndex - 1 < 0) return
        nextShowData = this.localData[this.nowIndex - 1]
        //此处省略........,自行补充
      }
      //   下一张
      if (type === 'next') {
        // 判断当前展示列表是否合法
        if (this.localData.length <= this.nowIndex + 1) return
        nextShowData = this.localData[this.nowIndex + 1]// 下一张的数据
        newDom.style.left = '100%'
      }

      // 新元素的内部结构
      const innerHtml = `
                <div class="scrollItem" style=" display: flex;  width: 100%; height: 100%; background-color: pink;">
                    <div class="img" style="width:50%; height:100%" >
                        <el-image src="${nextShowData.imgUrl}"></el-image>
                    </div>
                    <div class="messBox" style=" font-size: 16px; width:50%; height:100%; background-color: skyblue; ">
                        ${nextShowData.mess}
                    </div>
                </div>
        `
      // 插入子元素
      newDom.innerHTML = innerHtml
      fatherDom.appendChild(newDom)
    }
  }
}
</script>
<style lang='scss' scoped>
.container {
    width: 100%;
    height: 100%;
}

.container .windows {
    position: relative;
    left: 30%;
    font-size: 0px;
    overflow: hidden;
    width: 40%;
    height: 40%;
    border: 1px solid red;
}

.scrollBox {
    position: absolute;
    width: 100%;
    height: 100%;
    transition: all 0.5s;
}

.windows .scrollItem {
    display: flex;
    width: 100%;
    height: 100%;
    background-color: pink;
}

.windows .scrollItem .img {
    width: 50%;
    height: 100%;
}

.windows .messBox {
    font-size: 16px;
    width: 50%;
    height: 100%;
    background-color: skyblue;
}
</style>
相关推荐
y先森5 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy5 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
IT女孩儿6 小时前
CSS查缺补漏(补充上一条)
前端·css
emmm4597 小时前
html兼容性问题处理
html
我爱李星璇8 小时前
HTML常用表格与标签
前端·html
想自律的露西西★9 小时前
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
前端·javascript·css·vue.js·elementui·前端框架·html5
彪82510 小时前
第十章 JavaScript的应用 习题
javascript·css·ecmascript·html5
旧林84310 小时前
第八章 利用CSS制作导航菜单
前端·css
asleep70112 小时前
第8章利用CSS制作导航菜单
前端·css
乐闻x14 小时前
Vue.js 性能优化指南:掌握 keep-alive 的使用技巧
前端·vue.js·性能优化