ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

前端实现文字滚动(支持横向、纵向)

2021-08-02 12:01:04  阅读:811  来源: 互联网

标签:滚动 dayjs insideOffset inside INTERVAL 纵向 横向 const type


1.首先安装dayjs插件(后面唯一id使用)
day.js–一个轻量的处理时间和日期的JavaScript库

npm install dayjs --save

2.在main.js中引入dayjs插件插件

import dayjs from 'dayjs';
Vue.prototype.$dayjs = dayjs;

3.滚动组件

<template>
  <div 
    :id="id" 
    class="marquee-wrapper">
    <span 
      :style="translate" 
      class="marquee-inside">
      <slot />
    </span>
    <span 
      :class="`marquee-fake ${id}-fake`" 
      :style="fakeTranslate" />
  </div>
</template>

<script>
const FAKE_DOM_INTERVAL = 50;
export default {
  name: 'Marquee',
  props: {
    type: {
      type: String,
      default: 'horizontal' // horizontal(横)  vertical(纵)
    },
    speed: {
      type: Number,
      default: 1
    },
    interval: {
      type: Number,
      default: 50
    }
  },
  data() {
    return {
      id: '',
      timerId: null,
      distance: 0,
      fakeDistance: 0
    };
  },
  computed: {
    translate() {
      const direction = this.type === 'horizontal' ? 'X' : 'Y';
      return {
        transform: `translate${direction}(${this.distance}px)`
      };
    },
    fakeTranslate() {
      const direction = this.type === 'horizontal' ? 'X' : 'Y';
      return {
        transform: `translate${direction}(${this.fakeDistance}px)`
      };
    }
  },
  created() {
    this.id = `marquee-${this.$dayjs().valueOf()}`;
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    this.timerId && window.clearInterval(this.timerId);
  },
  methods: {
    init() {
      const wrapper = document.getElementById(this.id);
      if (!wrapper) return;
      const inside = wrapper.querySelector('.marquee-inside');
      let wrapperOffset;
      let insideOffset;
      if (this.type === 'horizontal') {
        wrapperOffset = wrapper.offsetWidth;
        insideOffset = inside.offsetWidth;
      }
      if (this.type === 'vertical') {
        wrapperOffset = wrapper.offsetHeight;
        insideOffset = inside.offsetHeight;
      }
      if (insideOffset > wrapperOffset) {
        this.createFakeDom(inside);
        this.timerId = window.setInterval(() => {
          this.run(insideOffset);
        }, this.interval);
      }
    },
    createFakeDom(inside) {
      const childNodes = inside.cloneNode(true).childNodes;
      const fakeDom = document.querySelector(`.${this.id}-fake`);
      for (let i = 0; i < childNodes.length; i++) {
        fakeDom.appendChild(childNodes[i]);
      }
      if (this.type === 'horizontal') {
        fakeDom.style.marginLeft = FAKE_DOM_INTERVAL + 'px';
      } else {
        fakeDom.style.marginTop = FAKE_DOM_INTERVAL + 'px';
      }
    },
    run(insideOffset) {
      this.distance -= this.speed;
      if (this.distance === -insideOffset - FAKE_DOM_INTERVAL)
        this.distance = insideOffset + FAKE_DOM_INTERVAL;
      this.fakeDistance -= this.speed;
      if (this.fakeDistance === -insideOffset * 2 - FAKE_DOM_INTERVAL)
        this.fakeDistance = FAKE_DOM_INTERVAL;
    }
  }
};
</script>
<style lang="scss" scoped>
.marquee-wrapper {
  width: 100%;
  height: 100%;
  overflow: hidden;

  .marquee-inside,
  .marquee-fake {
    display: inline-block;
  }
}
</style>

4.准备工作做好了,下面就是如何使用
注意:当高度(宽度)达不到时,是不能纵向(横向)滚动的。
(1)纵向使用

    <div
      class="content">
      <MarqueeBox 
        :interval="70" 
        type="vertical">
        文字....
      </MarqueeBox>
    </div>
import MarqueeBox from './MarqueeBox.vue';
export default {
  name: 'xxx',
  components: { detailDialog, MarqueeBox },
};
.content {
  height: 50px;
}

(2)横向滚动

    <div
      class="content">
      <MarqueeBox 
        :interval="70">
        文字....
      </MarqueeBox>
    </div>
import MarqueeBox from './MarqueeBox.vue';
export default {
  name: 'xxx',
  components: { detailDialog, MarqueeBox },
};
.content {
  white-space: nowrap; // 文字不换行
  width: 100px;
}

标签:滚动,dayjs,insideOffset,inside,INTERVAL,纵向,横向,const,type
来源: https://blog.csdn.net/weixin_46074961/article/details/119321945

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有