139.Vue获取文字长度和走马灯效果的实现

一次,要实现一个公告,需要走马灯效果。

发现,文字的宽度计算是需要用一个模拟的元素来计算的,因为我们用来实现走马灯效果的元素肯定是要设置overflow:hidden;的。

即,我们不可能用走马灯效果本身需要用到的div来计算文字的总宽度。

其次,也要注意各个端的font-size,文字的宽度与此相关,是否跑马灯也是相关的

案例效果如下:

Vue实现的代码如下:

文字长度不够一行则不跑马灯。

<template>
  <div class="wrap">
    <div class="icon-wrap">
      +
    </div>
    <div class="text-wrap" ref="textWrapDom">
      <div class="text-content" ref="textContentDom">
        {{text}}
      </div>
    </div>
    <!-- 空的dom,不展示,仅用于计算文字的宽度 -->
    <div class="virtual-dom" ref="virtualDom">
      {{text}}
    </div>
    <div class="more">
      更多
    </div>
  </div>
</template>

<script>
export default {
  name: 'HomeNotice',
  props: {
    layout: {},
    data: {},
  },
  computed: {
    // 跑马灯效果的文字
    text() {
      return '桃李春风一杯酒,江湖夜雨十年灯。西风吹老洞庭波,一夜湘君白发多。醉后不知天在水,满船清梦压星河。'
    }
  },
  data () {
    return {
      timer: null,
    }
  },
  mounted () {
    setTimeout(() => {
      this.move()
    }, 1000)
  },
  beforeDestroy() {
    clearInterval(this.timer)
    this.timer = null
  },
  methods: {
    move() {
      // 可视区域的宽度
      let curWidth = this.$refs.textWrapDom.offsetWidth
      // 所有文字的宽度
      let allWidth = this.$refs.virtualDom.offsetWidth

      console.log(curWidth, allWidth)
      // 位移距离
      let distance = 0
      if (allWidth > curWidth) {
        this.timer = setInterval(() => {
          distance = distance - 1
          // 如果位移超过文字宽度,则回到起点
          if (-distance >= (allWidth - 150)) {
            distance = 40
          }
          if (this.$refs.textContentDom) {
            this.$refs.textContentDom.style.transform = 'translateX(' + distance + 'px)'
          }
        }, 20)
      }
    },
  }
}
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
  list-style: none;
}
.wrap {
  margin: 5px 14px;
  height: 34px;
  display: flex;
}
.icon-wrap {
  display: flex;
  height: 34px;
  align-items: center;
  margin-right: 10px;
  flex: 0 0 20px;
  font-size: 20px;
}
.text-wrap {
  flex: 1;
  overflow: hidden;
}
.text-content {
  display: flex;
  align-items: center;
  height: 34px;
  font-size: 14px;
  font-weight: 300;
  color: rgba(0, 0, 0, 0.55);
  white-space: nowrap;
}
.more {
  position: relative;
  padding-left: 14px;
  padding-right: 8px;
  display: flex;
  align-items: center;
  height: 34px;
  font-size: 12px;
  font-weight: 400;
  color: #4FA3FF;
  box-shadow:  -7px 0px 7px -7px rgba(59, 61, 68, 0.1);
}
.virtual-dom {
  position:absolute;
  visibility: hidden;
  white-space: nowrap;
  z-index: -100;
}
</style>

complete.

posted @ 2020-11-07 15:12  海客无心x  阅读(1052)  评论(0编辑  收藏  举报