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

切换效果

页面结构变化

1.需求背景

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

2.解决思路

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

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

3.代码如下

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

<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>

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值