vue点击左右箭头左右滑动效果
代码:抽取组件
·
点击左右箭头左右滑动效果
代码:
<template>
<div class="vertical-scroll-wrap">
<svg class="left-prev"
v-if="showPrevIcon"
@click="prevItem">
<use href="#icon-icon-active-star"></use>
</svg>
<div class="vertical-scroll">
<div class="vertical-item">
<p v-for="(item,index) in list"
class="item"
:key="index">{{item.symbol}}</p>
</div>
</div>
<svg class="right-next"
v-if="showNextIcon"
@click="nextItem">
<use href="#icon-icon-active-star"></use>
</svg>
</div>
</template>
<script>
export default {
name: "test_new",
data () {
return {
showNextIcon: true,
clickNum: 0,
lastLeft: 0,
maxClickNum: 0, // 最大点击次数
};
},
props: {
list: {
type: Array,
default () {
return [
{
symbol: 'ETC/USDT'
},
{
symbol: 'ETH/USDT'
},
{
symbol: 'ETQ/USDT'
},
{
symbol: 'ETW/USDT'
},
{
symbol: 'ETR/USDT'
},
{
symbol: 'ETT/USDT'
},
{
symbol: 'ETY/USDT'
},
{
symbol: 'ETU/USDT'
},
{
symbol: 'ETI/USDT'
},
{
symbol: 'ETO/USDT'
}
]
}
}
},
computed: {
showPrevIcon () {
return this.clickNum > 0
}
},
methods: {
nextItem () {
// 如果点击次数小于数组长度-1时,执行左滑动效果。
if (this.clickNum < this.list.length - 1) {
//获取当前元素宽度
let width = document.querySelectorAll('.item')[this.clickNum].offsetWidth
// 获取最后一个元素距离左侧距离
let lastItemOffsetLeft = document.querySelectorAll('.item')[this.list.length - 1].offsetLeft
// 获取可视区域宽度
let lookWidth = document.querySelector('.vertical-scroll').clientWidth
console.log('移动前》》》', lastItemOffsetLeft, lookWidth);
// 如果最后一个元素距离左侧的距离大于可视区域的宽度,表示最后一个元素没有出现,执行滚动效果
if (lastItemOffsetLeft > lookWidth) {
// 公示:滚动距离(元素的magin-left值) = 负的它自己的长度 + 上一次滑动的距离
document.querySelector('.vertical-item').style.marginLeft = `${-width + this.lastLeft}px`
this.lastLeft = -width + this.lastLeft
this.clickNum += 1
// 记录到最后一个元素出现在可视区域时,点击次数的最大值。用于后面点击左侧箭头时判断右侧箭头的显示
this.maxClickNum = this.clickNum
}
/*
如果最后一个元素距离左侧的距离大于可视距离+自身的宽度,说明没有到最后一个, 显示右侧箭头,否则隐藏右侧箭头
注意:这里要加上其自身的宽度,否则要多点击一下才会隐藏。因为点击的时候实际上最后一个元素还没有滚动,
它距离左侧的距离是大于可视区域的(也就是说获取的是上一次点击之后,距离左侧的距离)
所以这里要加上其自身的宽度
看不懂的话不用管,反正加上就对了
*/
this.showNextIcon = lastItemOffsetLeft > lookWidth + width
}
},
prevItem () {
// 当点击次数大于0时才触发,这样当点击次数clickNum等于1的到时候,clickNum--等于0.根据计算属性的判断会隐藏掉左箭头
if (this.clickNum > 0) {
//获取当前元素宽度
let width = document.querySelectorAll('.item')[this.clickNum - 1].offsetWidth
// 公示:滚动距离(元素的magin-left值) = 它自己的长度 + 上一次滑动的距离
document.querySelector('.vertical-item').style.marginLeft = `${width + this.lastLeft}px`
this.lastLeft = width + this.lastLeft
//点击次数-1
this.clickNum--
if (this.clickNum < this.maxClickNum) {
this.showNextIcon = true
}
}
}
},
}
</script>
<style lang="scss" scoped>
.vertical-scroll-wrap {
margin-top: 50px;
display: flex;
justify-content: space-around;
align-items: center;
.vertical-scroll {
overflow: hidden;
flex: 1;
transition: all 0.3s ease;
.vertical-item {
transition: all 0.3s ease;
display: flex;
align-items: center;
p {
padding: 0 60px 0 0;
color: #fff;
}
}
}
.left-prev {
padding-right: 10px;
}
.right-next {
padding-left: 10px;
}
.left-prev,
.right-next {
width: 30px;
height: 30px;
vertical-align: middle;
}
}
</style>
抽取组件
<template>
<div class="optional-header">
<div class="vertical-scroll-wrap">
<div class="next-icon-wrap">
<i class="el-icon-arrow-left slide-arrow-left pointer"
:style="`color:${preIconColor}`"
v-if="showPrevIcon"
@click="prevItem"></i>
</div>
<div class="vertical-scroll"
:style="`height:${height}`">
<div class="content vertical-item-market">
<!-- 可滑动内容 -->
<slot></slot>
</div>
</div>
<div class="next-icon-wrap">
<i class="el-icon-arrow-right slide-arrow-right pointer"
v-if="showNextIcon"
:style="`color:${nextIconColor}`"
@click="nextItem"></i>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'slider',
data () {
return {
showOptionalHeader: true,
showNextIcon: true,
clickNum: 0,
lastLeft: 0,
maxClickNum: 0, // 最大点击次数
}
},
props: {
//高度
height: {
type: String,
default: '60px'
},
//prev颜色
preIconColor: {
type: String,
default: '#fff'
},
// next 颜色
nextIconColor: {
type: String,
default: '#fff'
},
// 数据条数
dataLength: {
type: [Number, String],
required: true
}
},
computed: {
showPrevIcon () {
return this.clickNum > 0
},
},
methods: {
nextItem () {
console.log('点击', this.dataLength);
// 如果点击次数小于数组长度-1时,执行左滑动效果。
if (this.clickNum < this.dataLength - 1) {
//获取当前元素宽度
let width = document.querySelectorAll('.item')[this.clickNum].getBoundingClientRect().width + 30
let lastItemOffsetLeft = document.querySelectorAll('.item')[this.dataLength - 1].offsetLeft
let lookWidth = document.querySelector('.vertical-scroll').clientWidth
// 如果最后一个元素距离左侧的距离大于可视区域的宽度,表示最后一个元素没有出现,执行滚动效果
if (lastItemOffsetLeft > lookWidth) {
// 公示:滚动距离(元素的magin-left值) = 负的它自己的长度 + 上一次滑动的距离
document.querySelector('.vertical-item-market').style.marginLeft = `${-width + this.lastLeft}px`
this.lastLeft = -width + this.lastLeft
this.clickNum += 1
// 记录到最后一个元素出现在可视区域时,点击次数的最大值。用于后面点击左侧箭头时判断右侧箭头的显示
this.maxClickNum = this.clickNum
}
/*
如果最后一个元素距离左侧的距离大于可视距离+自身的宽度,说明没有到最后一个, 显示右侧箭头,否则隐藏右侧箭头
注意:这里要加上其自身的宽度,否则要多点击一下才会隐藏。因为点击的时候实际上最后一个元素还没有滚动,
它距离左侧的距离是大于可视区域的(也就是说获取的是上一次点击之后,距离左侧的距离)
所以这里要加上其自身的宽度
看不懂的话不用管,反正加上就对了
*/
this.showNextIcon = lastItemOffsetLeft > lookWidth + width
}
},
prevItem () {
// 当点击次数大于0时才触发,这样当点击次数clickNum等于1的到时候,clickNum--等于0.根据计算属性的判断会隐藏掉左箭头
if (this.clickNum > 0) {
//获取当前元素宽度
let width = document.querySelectorAll('.item')[this.clickNum].getBoundingClientRect().width + 30
// 公示:滚动距离(元素的magin-left值) = 它自己的长度 + 上一次滑动的距离
document.querySelector('.vertical-item-market').style.marginLeft = `${width + this.lastLeft}px`
this.lastLeft = width + this.lastLeft
//点击次数-1
this.clickNum--
if (this.clickNum < this.maxClickNum) {
this.showNextIcon = true
}
}
},
async setNextIcon () {
//获取当前元素宽度
let lastItemOffsetLeft = document.querySelectorAll('.item')[this.optionalArr.length - 1]?.offsetLeft
let lookWidth = document.querySelector('.vertical-scroll')?.clientWidth
this.showNextIcon = lastItemOffsetLeft > lookWidth
}
},
mounted () {
}
}
</script>
<style lang='scss' scoped >
.vertical-scroll-wrap {
display: flex;
height: 100%;
width: 100%;
justify-content: space-around;
align-items: center;
.label-value {
color: var(--trade-symbol-market-table-symbol-color);
line-height: 16px;
margin-top: 3px;
font-size: 13px;
font-style: bold;
}
.slide-arrow-left {
margin-right: 6px;
color: var(--trade-heaer-nav-text-color);
}
.slide-arrow-right {
margin: 0 9px 0 6px;
color: var(--trade-heaer-nav-text-color);
}
.label {
color: var(--trade-common-font-color);
line-height: 16px;
}
.vertical-scroll {
overflow: hidden;
flex: 1;
transition: all 0.3s ease;
display: flex;
align-items: center;
.item {
flex-shrink: 0;
}
.vertical-item,
.vertical-item-market {
transition: all 0.3s ease;
display: flex;
align-items: center;
#item {
margin-right: 30px;
}
}
}
.left-prev {
padding-right: 10px;
}
.right-next {
padding-left: 10px;
}
.left-prev,
.right-next {
width: 30px;
height: 30px;
vertical-align: middle;
}
}
</style>
更多推荐
已为社区贡献9条内容
所有评论(0)