Preface: Recently, the function of text running lantern was used in the project. Be in line with can copy copy spirit, found several already realized this function on the net and function more component. It is a pity that the author has attached it to NPM and needs to use it in the way of guide package. If the group leader found that even a simple function to guide others to use the bag will be sprayed to death. I had no choice but to write one myself (based on Vue).Copy the code

Implementation principle: Timer + translateX effect

use

Import TextLoop from '@ / components/common/TextLoop / / here to change your store file path < text - loop: stringArray = "[' first paragraph text', 'the second long text... ', 'third']" gap="20px" :waitTime="1000" />Copy the code

Matters needing attention

Do not use Flex: 1 to give the parent element a definite width;Copy the code

Attach a code

<template> <div class="outBox" ref="outBox" v-if="! reFresh"> <div class="textBox" ref="box" @mouseenter="mouseenter" @mouseleave="mouseleave"> <span v-for="(item,index) in  stringArray" :key="index" :style="{ paddingRight: Gap}" >{{item}}</span> </div> </div> </template> <script> export default {props: {// {type: Array, default: []}, // Playback speed interval: {type: Number, default: 30}, // Each move too large pixels cause "very slow" visual effect movePx: {type: Number, default: 2}, // The space between two texts gap: {type: String, default: '10px'}, // The time each element stays displayed waitTime: {type: IsHoverStop: {type: Boolean, default: true}}, data() {return {timer: null, x: 0, isScrolling: true, index: 0, childWidth: 0, reFresh: False,}}, beforeDestroy() {// Clear timer clearInterval(this.timer)}, beforeDestroy() {// Clear timer clearInterval(this.timer)}, mounted() { this.$nextTick(() => { this.renderDom() }) }, methods: {renderDom() {const outBox = this.$refs.outbox; $refs.box const outWidth = outbox.offsetwidth; Const startX = outWidth box.style.transform = 'translateX(${startX}px)' this.x = startX // This.childwidth = [... box-nodes][this.index].offsetwidth this.timer = setInterval(() => {this.timer = setInterval(() => { if (! this.isScrolling) return const box = this.$refs.box if (! box) { return } const childNodes = [...box.childNodes] const totalChildWidth = childNodes.reduce((pre, cur) => pre + cur.offsetWidth, 0) box.style.transform = `translateX(${this.x}px)` this.x -= this.movePx if (-this.x >= totalChildWidth) { // This.x = startX this.index = 0 this.childWidth = childNodes[this.index].offsetwidth return} if ((-this.x >= this.childWidth) && this.waitTime) {// Wait for this.index+ this.childWidth += if the index element is passed childNodes[this.index].offsetWidth this.isScrolling = false setTimeout(() => { this.isScrolling = true }, this.waitTime); }}, this.interval)}, /** * @descript mouseenter(e) {if (! this.isHoverStop) return this.isScrolling = false; }, /** * @descript () {this.isscrolling = true; } } } </script> <style lang="scss" scoped> .outBox { width: 100%; overflow: hidden; .textBox { white-space: nowrap; } } </style>Copy the code