点击左右箭头左右滑动效果

代码:

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

Logo

前往低代码交流专区

更多推荐