vue-seamless-scroll 无缝滚动

6,235 阅读4分钟

“我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情

一、前言

最近需求又一次做yao,需要实现一个无缝滚动的效果,一开始我是直接自己造轮子,造是造出来了,但过程比较艰辛,还不如直接用现成的vue-seamless-scroll来做简单省事。

下面我带大家用vue-seamless-scroll实现一下功能哈。(直接用js实现横版无缝滚动的方法我也会放在最后一并讲解

目前支持上下左右无缝滚动,单步滚动,以及支持水平方向的手动切换功能

二、 过程

1、下载和引入

npm install vue-seamless-scroll --save

或者

yarn add vue-seamless-scroll

或者

https://cdn.jsdelivr.net/npm/vue-seamless-scroll@latest/dist/vue-seamless-scroll.min.js

下载之后引入

// 全局引入的方式 -- 在main.js里
import Vue from 'vue' 
import vueSeamlessScroll from 'vue-seamless-scroll' 
Vue.use(vueSeamlessScroll)


// 局部引入 ,在需要的vue文件里  也是本文使用的方式
import vueSeamlessScroll from 'vue-seamless-scroll'
export default {
  components: {
    vueSeamlessScroll
  }}
  

2、 使用

  <vue-seamless-scroll :data="arr" class="scroll" :class-option="defaultOption">
      <div v-for="item in arr" :key="item.id" class="item">
        {{ item.name }}
      </div>
    </vue-seamless-scroll>
    

首先是数据,需要绑定同个数组arr

   arr: [ 
       { name: '狗头1',id: 1 },
       { name: '狗头2',id: 2 },
       { name: '狗头3',id: 3 },
       { name: '狗头4',id: 4 },
       { name: '狗头5',id: 5 }]

其次是给vue-seamless-scroll设置一下配置参数,常见的基本在这里了(最后会放完整的参数列表),defaultOption放data里就行,也可以放计算属性里,

     // data里
     
     defaultOption: {
        step: 0.4, // 数值越大速度滚动越快
        limitMoveNum: 2, // 开始无缝滚动的数据量 this.dataList.length
        hoverStop: true, // 是否开启鼠标悬停stop
        direction: 0, // 0向下 1向上 2向左 3向右
        openWatch: true, // 开启数据实时监控刷新dom
        singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
        singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
        waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
      }
      
      
      // 计算属性里
      
      computed: {
        defaultOption1() {
          return {
            step: 0.4, // 数值越大速度滚动越快
            limitMoveNum: 2, // 开始无缝滚动的数据量 this.dataList.length
            hoverStop: true, // 是否开启鼠标悬停stop
            direction: 0, // 0向下 1向上 2向左 3向右
            openWatch: true, // 开启数据实时监控刷新dom
            singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
            singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
            waitTime: 1000 // 单步运动停止的时间(默认值1000ms)
          }
        }
  },
  

在之后是css样式的配置,因为该组件的实现原理是修改transform:translate的偏移量来实现效果的。

 // 外层盒子
.scroll {
  height: 30px;
  width: 300px;
  background: rgb(138, 192, 186);
}
// 里面的每一条
.item {
  height: 30px;
  width: 100%;
}

3、 效果

有水印哈,凑合看

soogif.gif

4、 完整配置项

keydescriptiondefaultval
step数值越大速度滚动越快1Number
limitMoveNum开启无缝滚动的数据量5Number
hoverStop是否启用鼠标hover控制trueBoolean
direction方向 0 往下 1 往上 2向左 3向右1Number
openTouch移动端开启touch滑动trueBoolean
singleHeight单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/10Number
singleWidth单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/30Number
waitTime单步停止等待时间(默认值1000ms)1000Number
switchOffset左右切换按钮距离左右边界的边距(px)30Number
autoPlay1.1.17版本前手动切换时候需要置为falsetrueBoolean
switchSingleStep手动单步切换step值(px)134Number
switchDelay单步切换的动画时间(ms)400Number
switchDisabledClass不可以点击状态的switch按钮父元素的类名disabledString
isSingleRemUnitsingleHeight and singleWidth是否开启rem度量falseBoolean
navigation左右方向的滚动是否显示控制器按钮,true的时候autoPlay自动变为falsefalseBoolean

简单的使用到这里就结束了,后面是我用js实现的横版无缝滚动,可以看看

三、 js实现横版无缝滚动

原理是定时器循环修改元素的left,代码如下

<div id="deviceplanlistScroll" class="detail">
  <div class="scrollBox">
    <span
      v-for="(item, index) in arr"
      :key="index + item.id"
      class="word"
    >
      {{ item.name }}
    </span>
  </div>
</div>

然后设置好样式

.scrollBox {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  display: flex;
}
.word {
  position: relative;
  color: #fff;
  font-weight: bold;
  margin: 0 2px;
  padding: 3px 10px;
  white-space: nowrap;
}

接下来就是获取到这些元素,定时去更新srcollBox的left数值,同时设立界限,当left值比scrollBox的元素还大时,赋初值重来。

mounted() {
this.init()
  },
  methods: {
    init() {
      const $container = document.getElementById('deviceplanlistScroll')
      const $content = document.getElementsByClassName('scrollBox')[0]
      $content.style.left = '0px'
      console.log($content.offsetWidth, $container.offsetWidth)
      setTimeout(() => {
        if ($content.offsetWidth > $container.offsetWidth) {
          this.deviceplanInterval = setInterval(() => {
            $content.style.left = $content.offsetLeft - 1 + 'px'
            if (Math.abs($content.offsetLeft) > $content.offsetWidth) {
              $content.style.left = $container.offsetWidth + 'px'
            }
          }, 50)
        }
      }, 1000)
    }
  }
  

效果

soogif (1).gif

ps: 最近不忙的话,会慢慢恢复更新。

Snipaste_2022-07-19_15-30-26.jpg