vue 实现跑马灯效果(无缝滚动)

项目上用到一个跑马灯的组件(支持文字、图片的无缝滚动),没有找到开源的合适的组件,索性自己实现一个。

实现原理:

用到HTML element 的两个属性:scrollLeft和scrollWidth。

  1. scrollLeft :读取或设置元素滚动条到元素左边的距离。

  2. scrollWidth:只读属性,是对元素内容宽度的一种度量,包括由于overflow溢出而在屏幕上不可见的内容

简单来说,就是获取滚动元素的scrollWidth,然后不断的设置scrollLeft的值就可以了。

show you my code:

👇下面是跑马灯组件:

<template>
  <div class="show-area" :style="{ width: `${width}px`, height: `${height}px` }">
    <div class="scroll-area">
      <!-- 设置margin,使内容 有从无到有的出现效果 -->
      <div class="slot-container" :style="{ margin: `0 ${width}px` }">
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import Vue, { PropType } from 'vue'

export default Vue.extend({
  props: {
    // 自定义跑马灯宽度
    width: {
      type: Number,
      default() {
        return 400
      }
    },
    // 自定义跑马灯高度
    height: {
      type: Number,
      default: 50
    }
  },
  data() {
    return {}
  },
  mounted() {
    // 在mounted阶段,才可以获取真实DOM节点
    const showArea: any = document.querySelector('.show-area')
    //从左到右滚动,首先把滚动条置到元素的最右边
    showArea.scrollLeft = showArea.scrollWidth
    function f() {
      //如果滚动条到了元素的最左边,那么把它再初始化到最右边
      if (showArea.scrollLeft < 3) {
        showArea.scrollLeft = showArea.scrollWidth
      } else {
        //每次滚动条向左移动2,改变speed可以调整滚动速度
        const speed = 2
        showArea.scrollLeft -= speed
      }
      //使用requestAnimationFrame,优化滚动效果
      //requestAnimationFrame使得滚动和机器帧率同步
      requestAnimationFrame(f)
    }
    requestAnimationFrame(f)
  }
})
</script>

<style lang="scss" scoped>
.show-area {
  // height: 50px;
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  .scroll-area {
    display: inline-block;
    .slot-container {
      display: inline-block;
    }
  }
}
</style>
复制代码

👇下面是一个demo:

<template>
  <div class="carousel-c">
    <Carousel>
      <div v-for="item in items" :key="item">
        {{ item }}
      </div>
    </Carousel>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Carousel from '@components/common/carousel/carousel'

export default Vue.extend({
  components: {
    Carousel
  },
  data() {
    return {
      items: ['文字1  ', '文字2  ', '文字3  ', '文字4  ', '文字5  ', '文字6  ']
    }
  }
})
</script>

<style scoped lang="scss"></style>

复制代码
分类:
前端
标签: