vue marquee 思路总结(附具体代码)

需求:项目中需要做一个通知的跑马灯,试了很多方案,最后用了下面这种,感谢大佬的博客
原博客地址: 点这里
最终的效果:
在这里插入图片描述
剖析代码(本菜鸡第一次看有点绕)
marquee.vue的源代码

<template>
  <div class="marquee-wrap">
    <div class="scroll">
      <p class="marquee">{{ text }}</p>
      <p class="copy"></p>
    </div>
    <!-- <p class="getWidth">{{ text }}</p> -->
  </div>
</template>

<script>
/**
 * 调用组件时将要展示的文字传递进来 val
 */
export default {
  name: 'marquee',
  props: ['val'],
  data() {
    return {
      timer: null,
      text: ''
    }
  },
  created() {
    const timer = setTimeout(() => {
      this.move()
      clearTimeout(timer)
    }, 200)
  },
  mounted() {
    for (const item of this.val) {
         this.text += ' ' + item
    }
  },
  methods: {
    move() {
      const maxWidth = document.querySelector('.marquee-wrap').clientWidth
      const width = document.querySelector('.getWidth').scrollWidth
      console.log(width, maxWidth)
      if (width <= maxWidth) return
      const scroll = document.querySelector('.scroll')
      const copy = document.querySelector('.copy')
      copy.innerText = this.text
      let distance = 0
      this.timer = setInterval(() => {
        distance -= 1
        if (-distance >= width) {
          distance = 30
        }
        scroll.style.transform = 'translateX(' + distance + 'px)'
      }, 20)
    }
  },
  beforeDestroy() {
    clearInterval(this.timer)
  }
}
</script>

<style scoped>
.marquee-wrap {
  width: 100%;
  overflow: hidden;
  position: relative;
}
.marquee {
  margin-right: 30px;
}
p {
  word-break: keep-all;
  white-space: nowrap;
  font-size: 0.26rem;
}
.scroll {
  display: flex;
}
.getWidth {
  word-break: keep-all;
  white-space: nowrap;
  position: absolute;
  opacity: 0;
  top: 0;
} 
</style>

根据自己的实际需要,修改了一点点细节
具体思路:有两个包含文字的p标签,分别是marquee和copy,他们的父标签scroll设置display:flex;使得两个p标签在一行,最外层的marquee-wrap设置overflow:hidden;每次创建组件调一下move方法,主要是逻辑都在move方法里面

<template>
  <div class="marquee-wrap">
    <div class="scroll">
      <p class="marquee">{{ val }}</p>
      <p class="copy">{{ val }}</p>
    </div>
  </div>
</template>

<script>
export default {
  name: 'marquee',
  props: ['val'],
  data() {
    return {
      timer: null
    }
  },
  created() {
    const timer = setTimeout(() => {
      this.move()
      clearTimeout(timer)
    }, 200)
  },
  mounted() {},
  methods: {
    move() {
	   //外层容器的宽度
      const maxWidth = document.querySelector('.marquee-wrap').clientWidth
      //内容总宽度:scrollWidth:获取指定标签内容层的真实宽度(可视区域宽度+被隐藏区域宽度)
      const width = document.querySelector('.marquee').scrollWidth
      if (width <= maxWidth) return	//如果要展示的内容的宽度小于外层容器宽度,不滚动,直接return
      const scroll = document.querySelector('.scroll')//获取scroll,后面要设置样式
      let distance = 0 //初始化一个distance
      this.timer = setInterval(() => { //开启定时器
        distance -= 1 //每20秒distance = distance - 1
        if (-distance >= width) { //如果所有的内容都已经滚动出去
          distance = 30 //重置distance(和样式里面marquee的margin-right一致!!!)
        }
        scroll.style.transform = 'translateX(' + distance + 'px)' //将scroll迅速切换到distance的位置(看起来就无缝衔接了)
      }, 20)
    }
  },
  beforeDestroy() {
    clearInterval(this.timer)//组件销毁之前清掉timer
  }
}
</script>

<style scoped lang="less">
.marquee-wrap {
  width: 100%;
  overflow: hidden;
  .scroll {
    display: flex;
    p {
      word-break: keep-all;
      white-space: nowrap;
      font-size: 0.26rem;
    }
    .marquee {
      margin-right: 30px;
    }
  }
}
</style>

clientWidth的实际宽度
clientWidth = width+左右padding

scrollWidth实际宽度
scrollWidth:获取指定标签内容层的真实宽度(可视区域宽度+被隐藏区域宽度)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值