阅读量:0
切换效果
页面结构变化
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>