Vue跑马灯marquee组件(双端通用)

目录

一、实现效果

二、实现过程

三、js版本源码

四、Vue组件源码


一、实现效果

二、实现过程

        前言:最开始用间隔器方案制作了一个跑马灯,但是放在移动端中会出现严重的掉帧卡顿现象,于是整理思路后采用transition方案制作一个从右到左的动画处理问题

       思路整理:

        1.过渡是需要设定时间的,但是跑马灯中的文本可能是长短不一的

        解决方案:根据文本的总宽度(即文本总长)设定过渡时间,假设文本宽度500px,我们将其除以50,即过渡时间为10s

        原生js表示如下:

    const text = document.getElementsByClassName("text")[0]  // 文本
    const textWidth = text.clientWidth  // 文本的总宽度
    const tranTime = textWidth / 50  // 根据文本宽度设置过渡时间
    text.style.transition = "left " + tranTime + "s linear"  // 滚动前绑定过渡属性

        2.要想持续滚动需要重复触发滚动的事件

        解决方案:通过上文的过渡时间设定一个重复时间

        原生js表示如下:

    const againTime = tranTime * 1000 + 1000  // 重新开始滚动时间计算(动态)
    // 开始滚动
    function textRoll() {
      // 滚动操作
      // ``````
      setTimeout(() => {
        textRoll()
      }, againTime);
    }

        3.接下来实现文本滚动效果

                1) 先将文本设定在容器最右侧

                2) 为文本绑定设定好的过渡属性,例:transition: left 10s linear

                3) 因为有过渡属性,此时再将文本设定到容器最左侧,就会产生一个从右向左的移动的

过渡

        原生js表示如下:

    function textRoll() {
      text.style.transition = "left " + tranTime + "s linear"  // 滚动前绑定过渡属性
      text.style.left = -textWidth + "px"  // 向容器最左移动
      setTimeout(() => {
        setTimeout(() => {
          textRoll()
        }, 0);
      }, againTime);
    }

        4.到目前就能有一次完整的滚动了,接下来是定义重新滚动

        让文本回到容器最右侧,但是目前文本已经有过渡属性了,如果改变其left会导致他从左向右滚动,所以要先清除过渡属性,再改变其left到容器最右侧,然后用一开始设定的再次滚动时间绑定定时器

    function textRoll() {
      text.style.transition = "left " + tranTime + "s linear"  // 滚动前绑定过渡属性

      text.style.left = -textWidth + "px"  // 向容器最左移动

      setTimeout(() => {
        // 还原文本位置
        text.style.transition = ""  // 还原前需清除过渡
        text.style.left = wrapperWidth + "px"
        setTimeout(() => {
          textRoll()
        }, 0);
      }, againTime);
    }

三、js版本源码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>跑马灯</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    body {
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .wrapper {
      width: 60%;
      height: 30px;
      background-color: #000;
      overflow: hidden;
      position: relative;
    }

    .text {
      color: #fff;
      white-space: nowrap;
      line-height: 30px;
      position: absolute;
    }
  </style>
</head>
<body>
  <div class="wrapper">
    <div class="text">如何四纪为天子,不及卢家有莫愁。</div>
  </div>

  <script>
    const wrapper = document.getElementsByClassName("wrapper")[0]  // 容器
    const text = document.getElementsByClassName("text")[0]  // 文本

    const wrapperWidth = wrapper.clientWidth  // 容器的总宽度
    const textWidth = text.clientWidth  // 文本的总宽度

    text.style.left = wrapperWidth + "px"  // 开始滚动前设定文本在容器最右侧以外
    const tranTime = textWidth / 50  // 根据文本宽度设置过渡时间
    const againTime = tranTime * 1000 + 1000  // 重新开始滚动时间计算(动态)

    setTimeout(() => {
      textRoll()
    }, 0);

    // 开始滚动
    function textRoll() {
      text.style.transition = "left " + tranTime + "s linear"  // 滚动前绑定过渡属性

      text.style.left = -textWidth + "px"  // 向容器最左移动

      setTimeout(() => {
        // 还原文本位置
        text.style.transition = ""  // 还原前需清除过渡
        text.style.left = wrapperWidth + "px"
        setTimeout(() => {
          textRoll()
        }, 0);
      }, againTime);
    }
  </script>
</body>
</html>

四、Vue组件源码

<template>
  <div class="mobile-marquee">
    <img src="~assets/img/home/notice/notice.png" alt="" />
    <div class="mobile-marquee-wrapper" ref="wrapper">
      <div
        class="mobile-marquee-text"
        ref="text"
        :style="{ 'left': textLeft, 'transition': textTransition }"
      >
        {{ text }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      text:
        "海外徒闻更九州,他生未卜此生休。 空闻虎旅传宵柝,无复鸡人报晓筹。 此日六军同驻马,当时七夕笑牵牛。 如何四纪为天子,不及卢家有莫愁。",
      url: "",
      textLeft: "",
      textTransition: ""
    };
  },
  methods: {
    // 跑马灯运作
    marquee() {
      const _this = this
      const wrapperWidth = this.$refs.wrapper.clientWidth; // 容器的总宽度
      const textWidth = this.$refs.text.clientWidth; // 文本的总宽度
      const transTime = textWidth / 50; // 根据文本宽度设置过渡时间
      const againTime = transTime * 1000 + 1000; // 重新开始滚动时间计算(动态)

      this.textLeft = wrapperWidth + "px"; // 开始滚动前设定文本在容器最右侧以外
      
      setTimeout(() => {
        textRoll()
      }, 0);

      function textRoll() {
        _this.textTransition = "left " + transTime + "s linear"; // 滚动前绑定过渡属性
        _this.textLeft = -textWidth + "px"; // 向容器最左移动
        setTimeout(() => {
          // 还原文本位置
          _this.textTransition = "none"; // 还原前需清除过渡
          _this.textLeft = wrapperWidth + "px";
          setTimeout(() => {
            textRoll();
          }, 0);
        }, againTime);
      }
    },
  },
  mounted() {
    this.marquee();
  }
};
</script>

<style>
.mobile-marquee {
  display: flex;
  align-items: center;
  height: 40px;
  margin: 0 16px;
}

.mobile-marquee-wrapper {
  flex: 1;
  height: 40px;
  overflow: hidden;
  position: relative;
}

.mobile-marquee img {
  width: 14px;
  height: 12px;
  margin-right: 7px;
}

.mobile-marquee-text {
  color: #333;
  white-space: nowrap;
  line-height: 40px;
  position: absolute;
}
</style>

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue跑马灯 (marquee) 组件是一种常见的UI组件,可以用于在页面上展示滚动的文字或图片。以下是一个简单的Vue跑马灯组件示例: ```vue <template> <div class="marquee"> <div class="marquee-content" :style="{transform: 'translateX(' + position + 'px)'}"> <slot></slot> </div> </div> </template> <script> export default { data() { return { position: 0, interval: null }; }, mounted() { this.interval = setInterval(() => { const content = this.$el.querySelector('.marquee-content'); const width = content.offsetWidth; const parentWidth = this.$el.offsetWidth; if (width > parentWidth) { this.position -= 1; if (Math.abs(this.position) >= width) { this.position = parentWidth; } } }, 20); }, beforeDestroy() { clearInterval(this.interval); } }; </script> <style> .marquee { overflow: hidden; } .marquee-content { display: inline-block; white-space: nowrap; } </style> ``` 在上面的示例中,我们定义了一个名为 `marquee` 的组件,它包含一个名为 `marquee-content` 的子组件,用于包裹滚动的内容。我们使用CSS的 `overflow` 属性设置父元素为 `hidden`,以隐藏超出父元素边界的内容。 在 `mounted` 钩子函数中,我们使用 `setInterval` 函数定时更新 `marquee-content` 的 `transform` 属性,以实现滚动效果。我们在 `beforeDestroy` 钩子函数中清除定时器,以避免内存泄漏。 在使用 `marquee` 组件时,我们可以将需要滚动的内容插入到组件中,例如: ```vue <marquee> <img src="image1.jpg" alt="Image 1"> <img src="image2.jpg" alt="Image 2"> <img src="image3.jpg" alt="Image 3"> </marquee> ``` 在上面的示例中,我们插入了三张图片到 `marquee` 组件中。这些图片将在组件中滚动,并且当它们的宽度超出父元素的宽度时,它们将自动滚动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值