123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- <template>
- <!-- 文本超出,左右按钮滚动 -->
- <div ref="swiperScroll" class="left-right-swiper-scroll-box">
- <!-- 左边按钮 -->
- <div v-show="showLeftIcon" @click="handleLeftClick" class="scroll-icon left-icon">
- <i ></i>
- </div>
- <!-- 中间滚动区域 -->
- <div ref="swiperScrollContent" class="swiper-scroll-content">
- <slot></slot>
- </div>
- <!-- 右边按钮 -->
- <div v-show="showRightIcon" @click="handleRightClick" class="scroll-icon right-icon">
- <i ></i>
- </div>
- </div>
- </template>
- <script>
- export default {
- name: 'leftRightSwiperScroll',
- props: {
- swiperList: {
- type: Object,
- default: () => {
- return {};
- }
- }
- },
- data() {
- return {
- showRightIcon: false, // 是否显示右箭头
- swiperScrollWidth: 0, // 盒子的宽度
- swiperScrollContentWidth: 0, // 内容的宽度
- maxClickNum: 0, // 最大点击次数
- lastLeft: 0, // 上次滑动距离
- clickNum: 0, // 点击次数
- childrenList: [] // 传进来的子元素
- }
- },
- computed: {
- showLeftIcon() {
- return this.clickNum > 0
- }
- },
- mounted() {
- // 获取 HTMLCollection 转为 数组
- this.childrenList = [...this.$refs.swiperScrollContent.children];
- console.log('childrenList--->', this.childrenList);
- console.log('swiperScroll--->', this.$refs.swiperScroll);
- console.log('swiperScrollContent--->', this.$refs.swiperScrollContent);
- // 盒子的宽度
- this.swiperScrollWidth = this.$refs.swiperScroll.getBoundingClientRect().width;
- // 内容的宽度
- this.swiperScrollContentWidth = this.$refs.swiperScrollContent.getBoundingClientRect().width;
- // 比较盒子的宽度,跟内容的宽度:判断是否需要展示右边的按钮
- if(this.swiperScrollWidth < this.swiperScrollContentWidth) {
- this.showRightIcon = true;
- }
- console.log('盒子的宽度--->', this.swiperScrollWidth );
- console.log('内容的宽度--->', this.swiperScrollContentWidth);
- console.log('this.showRightIcon',this.showRightIcon)
- },
- methods: {
- // 点击右箭头(左侧滚动)
- handleRightClick() {
- // 如果点击次数小于数组长度-1时,执行左滑动效果。
- if (this.clickNum < this.childrenList.length - 1) {
- // 获取当前元素宽度
- let width = this.childrenList[this.clickNum].getBoundingClientRect().width;
- console.log(this.childrenList[this.clickNum], this.childrenList[this.clickNum].getBoundingClientRect());
- // 获取最后一个元素距离左侧的距离
- let lastItemOffsetLeft = this.childrenList[this.childrenList.length - 1].offsetLeft;
- // 获取最后一个元素宽度
- let lastWidth = this.childrenList[this.childrenList.length - 1].getBoundingClientRect().width;
- console.log('lastItemOffsetLeft-->', lastItemOffsetLeft, this.childrenList[this.childrenList.length - 1].getBoundingClientRect());
- // 获取可视区域宽度
- const lookWidth = this.$refs.swiperScroll.clientWidth;
- console.log('获取可视区域宽度-->lookWidth', lookWidth);
- // 如果最后一个元素距离左侧的距离+自身的宽度大于可视距离,表示最后一个元素没有出现,执行滚动效果
- if (lastItemOffsetLeft + lastWidth > lookWidth) {
- // 滚动距离(元素的magin-left值) = 负的它自己的长度 + 上一次滑动的距离
- this.$refs.swiperScrollContent.style.marginLeft = `${-width + this.lastLeft}px`;
- this.lastLeft = -width + this.lastLeft;
- // 点击次数+1
- this.clickNum++;
- // 记录到最后一个元素出现在可视区域时,点击次数的最大值。用于后面点击左侧箭头时判断右侧箭头的显示
- this.maxClickNum = this.clickNum;
- }
- // 如果最后一个元素距离左侧的距离小于于可视距离,需要隐藏右侧箭头
- let timer = setTimeout(() => {
- // 重新:获取最后一个元素距离左侧的距离
- let lastItemOffsetLeft2 = this.childrenList[this.childrenList.length - 1].offsetLeft;
- console.log('lastItemOffsetLeft2-新的->', lastItemOffsetLeft2);
- if(lastItemOffsetLeft2 + lastWidth <= lookWidth) {
- this.showRightIcon = false;
- }
- clearTimeout(timer);
- }, 200);
- }
- },
- // 点击左箭头(右侧滚动)
- handleLeftClick() {
- // 当点击次数大于0时才触发,这样当点击次数clickNum等于1的到时候,clickNum--等于0.根据计算属性的判断会隐藏掉左箭头
- if (this.clickNum > 0) {
- // 获取当前元素宽度
- let width = this.childrenList[this.clickNum - 1].getBoundingClientRect().width;
- // 公示:滚动距离(元素的magin-left值) = 它自己的长度 + 上一次滑动的距离
- this.$refs.swiperScrollContent.style.marginLeft = `${this.lastLeft + width}px`
- this.lastLeft = width + this.lastLeft;
- // 点击次数-1
- this.clickNum--;
- // 如果点击次数小于最大点击次数,说明最后一个元素已经不在可是区域内了,显示右箭头
- if (this.clickNum < this.maxClickNum) {
- this.showRightIcon = true;
- }
- }
- }
- }
- }
- </script>
- <style lang='scss' scoped>
- .left-right-swiper-scroll-box {
- position: relative;
- display: flex;
- width: 1145px;
- overflow: hidden;
- transition: all 0.3s;
- padding: 0 30px;
- margin-right: 5px;
- .scroll-icon {
- position: absolute;
- top: 0;
- width: 30px;
- height: 70px;
- z-index: 9;
- cursor: pointer;
- background-image: linear-gradient(270deg, invalid gradient);
- z-index: 1000;
- i {
- position: absolute;
- top: 5px;
- width: 20px;
- height: 20px;
- }
- &.left-icon {
- left: 0;
- background: url("~@/assets/images/img-mask-left.png") 0 0 no-repeat;
- // i {
- // left: 0;
- // background: url("~@/assets/images/icon-arrow-left.png") 0 0 no-repeat;
- // }
- }
- &.left-icon:hover{
- left: 0;
- background: url("~@/assets/images/icon-arrow-left.png") 0 0 no-repeat;
- }
- &.right-icon {
- right: 0;
- background: url("~@/assets/images/img-mask-right.png") 0 0 no-repeat;
- // i {
- // right: 0;
- // background: url("~@/assets/images/icon-arrow-right.png") 0 0 no-repeat;
- // }
- }
- &.right-icon:hover {
- right: 0;
- background: url("~@/assets/images/icon-arrow-right.png") 0 0 no-repeat;
- }
- }
- .swiper-scroll-content {
- width: fit-content;
- display: flex;
- flex-wrap: nowrap;
- white-space: nowrap;
- transition: all 0.3s;
- }
- }
- </style>
|