vue中实现文字的滚动
需求场景如下:
- 基本布局如下:
<template>
<div class="" v-if="canShowTypeC.length">
<span class=""></span> // 图标
<div class="" ref="overflowbox">
<p :class="scrollFlag ? 'bkpackage_typeC_middle_p' : ''" ref="overflowP">
<span style="display:inline-block;" ref="overflowSpan"><span v-for="(item, index) in canShowTypeC" :key="item.platform">{{ item.platform + ':' + item.version + '有用信息' + ( (index == canShowTypeC.length -1) ? '' : ',') }}
</span>有用信息。
</span>
</p>
</div>
<a href="javascript:;" class="" @click="handleClick">确认已完成</a>
</div>
</template>
- 页面表现:
-
基本介绍
- 一个图标, 中间是信息, 右侧是确认
- 布局: 大的div: flex布局, 图标和确认定宽, 中间信息部分是flex:1
- 大div显示的条件是数组的长度> 0, 中间信息也与数组有关
-
实现思路
- 通过比较p标签里面内容的长度与p标签的长度: 注意这里要将p的第一个span设置成inline-block, span本身是获取不到长度的
- 给外面的p标签动态绑定class,控制里面的内容是否滚动, 利用css3的animate属性
-
具体实现
- 给p 和 p的一个span 设置ref, 获取dom元素, 分别获得 两个元素的clientWidth
- 比较 两个clientWidth, 注意实际的大小.
- 如果相等的话, 就将控制滚动class的类绑定到p上
-
坑
- 先使用的computed属性, 用返回true 和 false 来控制是否滚动
- 然而,在实际操作的时候发现, 根本获取不到dom, 原因是因为执行这个计算属性的时候这两个dom元素还没有被渲染
- 使用watch, 监听数组的变化, 然后定义一个变量来控制是否滚动, 通过比较大小来控制变量的true和false
- 然而, 还是获取不到dom, 这里使用nextTick()来解决一个渲染的问题
- 先使用的computed属性, 用返回true 和 false 来控制是否滚动
-
结果
- 能实现预期功能
- 不能监听窗口大小变化而改变是否滚动
-
关键代码
watch: { canShowTypeC: function (val) { if(this.canShowTypeC.length > 0) { this.$nextTick(() => { var elp = this.$refs.overflowP var elspan = this.$refs.overflowSpan if(elspan.clientWidth == elp.clientWidth) { this.scrollFlag = true } else { this.scrollFlag = false } }) } }
.middle{
flex: 1;
overflow: hidden;
.bkpackage_typeC_middle_p {
width: 100%;
white-space: nowrap;
animation: 10s wordsLoop linear infinite normal;
}
}
@keyframes wordsLoop {
0% {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
}
@-webkit-keyframes wordsLoop {
0% {
transform: translateX(100%);
-webkit-transform: translateX(100%);
}
100% {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
}