Vue.js 文本交替滚动

1.前言

当一段文本需要单行显示,但是又限于容器宽度无法完全展示时,我们需要对其滚动展示,所以就有了这个插件,如图:

2.封装思路

  • 使用js模拟循环滚动的动画,容器宽度固定且超出隐藏,文本元素禁止换行,为其动态设定位移
  • 通过Vue指令开启该效果
  • 对比容器宽度和文本宽度,当文本宽度大于容器宽度是,开启定时器为文本元素动态设定位移,定时器id可以存储到容器标签中
  • 位移的终点位于取决于文本宽度与容器宽度的差值
  • 当指令的值发生变动时,要重新计算容器宽度和文本宽度,重置定时器

3.代码

function autoScroll(el) {
        //找到容器装载文本的容器
        var content_box = el.querySelector('span')
        //计算容器宽度
        var wrap_width = el.clientWidth
        //console.log('容器宽度 = ', wrap_width)
        //console.log('文本宽度 = ', content_box.clientWidth)
        //判断内容是否溢出
        if (content_box.clientWidth > wrap_width) {
            //如果内容移除

            //外层容器超出隐藏
            el.style.overflow = 'hidden'

            var now_position = 0 //当前位置 默认0
            var direction = 'left' //移动方向 一开始向左移动,到顶后向右移动
            var target = wrap_width - content_box.clientWidth  //向左移动时,到哪个位置就返回
            var rest_time = 40 //动画暂停时间
            //使用定时器实时修改位移
            var timer = setInterval(() => {
                //判断是否处于暂停状态 只有不是暂时状态才进行移动
                if (rest_time <= 0) {
                    //方向判断
                    if (direction == 'left') {
                        now_position--
                    } else {
                        now_position++
                    }
                    //如果左移到底 则调转方向向右
                    if (now_position < target) {
                        direction = 'right'
                        //重置暂停动画的时间
                        rest_time = 20
                    }
                    //如果右移到底 则调转方向向左 并暂停一段时间
                    if (now_position > 0) {
                        direction = 'left'
                        //重置暂停动画的时间
                        rest_time = 40
                    }
                    //更新位置
                    content_box.style.transform = `translateX(${now_position}px)`
                }
                //减少暂时状态的时间
                if(rest_time > 0){
                    rest_time--
                }
            }, 50)
            //console.log('定时器id = ', timer)
            //将定时器id挂载到容器中
            el.scroll_id = timer
        } else {
            //定时器id
            el.scroll_id = null
        }
    }
    //Vue指令注册 
    Vue.directive('scroll', {
        // 当被绑定的内容插入到 DOM 中时……
        inserted: function (el, binding) {
            //创建容器装载文本
            var content_box = document.createElement('span')
            content_box.style.display = 'inline-block'
            //不允许换行
            content_box.style.whiteSpace = 'nowrap'
            //将内容填入容器中
            content_box.innerHTML = binding.value
            //将文本容器添加到元素中
            el.appendChild(content_box)
            //开启功能
            autoScroll(el)
        },
        update: function (el, binding) {
            //找到定时器id
            var timer = el.scroll_id
            console.log('定时器id = ', timer)
            //清除定时器
            clearInterval(timer)
            //找到容器装载文本的容器
            var content_box = el.querySelector('span')
            //文本替换
            content_box.innerHTML = binding.value
            //样式重置
            content_box.style.transform = `translateX(0)`
            //开启功能
            autoScroll(el)
        }
    })

4.使用方法

  • 当前标签使用v-scroll指令传值
  • 设定固定的容器宽度,当前标签不要设定padding,如果需要,那就在外面再包一层
<div v-scroll="msg" style="width:200px;"></div>
posted @ 2022-04-24 14:45  ---空白---  阅读(184)  评论(0编辑  收藏  举报