切换效果
页面结构变化
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>