Vue中消息横向滚动时setInterval清不掉的问题及解决方法

 更新时间:2019年08月23日 14:29:19   作者:雨夜望月  
最近在做项目时,需要进行两个组件联动,一个轮询获取到消息,然后将其传递给另外一个组件进行横向滚动展示,结果滚动的速度越来越快。接下来通过本文给大家分享Vue中消息横向滚动时setInterval清不掉的问题及解决方法,感兴趣的朋友一起看看吧

最近在做项目时,需要进行两个组件联动,一个轮询获取到消息,然后将其传递给另外一个组件进行横向滚动展示,结果滚动的速度越来越快。这里记录一下来提醒自己。消息滚动的代码在最下面,方便下次使用。

问题背景: 最近在做一个需求,组件A获取消息采用的是轮询,组件A获取到新的消息后,将组件A中的消息传递给另外一个组件B,当组件B接收到消息时就让消息在页面上滚动播放。

实现思路: 这个项目应用的框架为VUE,当组件A获取到新的消息之后,就触发中央事件总线,在组件B中进行事件监听,将其添加进入一个数组,当判断定时器没有运动时,就触发滚动的函数。消息滚动的函数是从消息数组中提取出第一条,然后利用定时器进行消息滚动,当消息滚动到边缘时清除定时器。

问题:消息在滚动的过程中,该开始还能够按照给定的速度进行滚动,可是当时间变长后就会出现消息滚动的速度越来越快的问题。

原因:当出现这个问题时,我第一个念头就是setInterval没有被清掉,因为当定时器没有清掉之后又再次调用定时器就会导致多个定时器同时执行,比如第一次是一个计时器,再点一下是就是两个定时器,这时候每次就是+2,所以速度不断提升。我看了一下我设置的滚动函数,里面当消息滚动到边缘时,就清除这个定时器,所以在滚动函数中没有问题。我又看了下中央事件总线的事件监听器,发现问题在这里。因为我在判断一个定时器是否被销毁时,直接判断其类型是 数字 还是 null,由于当定时器开始运行时,每一次返回的都是一个ID(数字),而不是一开始的对象,导致当一条消息开始滚动时,又接收到一条新的消息,然后就使得两个定时器同时运行,从而出现这个问题。

解决方式:当消息滚动到盒子边缘销毁定时器时,将其赋值为null,然后修改中央事件的事件监听,将其判断没有定时器的条件修改为null,然后满足条件的调用消息滚动函数。

横向滚动的代码:

<!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      #title {
        position: relative;
        width: 10%;
        margin: 30px auto;
        line-height: 30px;
        height: 30px;
        border: 1px solid red;
        overflow: hidden;
      }
      #content {
        position: absolute;
        left: 0;
        line-height: 30px;
        display: inline-block;
      }
    </style>
  </head>
  <body>
    <div id="title">
      <span id="content">123</span>
    </div>
    <script>
      var wrapEle = document.getElementById('title');
      let contentEle = document.getElementById('content');
      let arr = [
        {news: '这是一条新闻'}
      ];
      let timer = null;
      move(wrapEle, contentEle);
      function move(wrap, item) {
        clearInterval(timer);
        if (!arr.length) { return false;}
        item.innerHTML = arr[0].news;
        arr.splice( 0, 1 );
        let allWidth = getCurrentStyle(wrap, 'width');
        let itemWidth = getCurrentStyle(item, 'width');
        item.style.left = allWidth + 'px';
        let speed = 2;
        let time = 50;
        timer = setInterval( () => {
          let itemPlace = getCurrentStyle(item, 'left');
          if (itemPlace < -itemWidth) {
            clearInterval(timer);
          }
          item.style.left = itemPlace - speed + 'px';
        }, time)
      }
      function getCurrentStyle (ele, attr) {
        return window.getComputedStyle ? parseInt(window.getComputedStyle(ele, null)[attr]) : parseInt(ele.currentStyle[attr] );
      }
    </script>
  </body>
  </html>

总结

以上所述是小编给大家介绍的Vue中消息横向滚动时setInterval清不掉的问题及解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

相关文章

  • Vue常用传值方式、父传子、子传父及非父子实例分析

    Vue常用传值方式、父传子、子传父及非父子实例分析

    这篇文章主要介绍了Vue常用传值方式、父传子、子传父及非父子,结合实例形式分析了vue.js常见的传值方式及相关操作注意事项,需要的朋友可以参考下
    2020-02-02
  • vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)

    vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示)

    这篇文章主要介绍了vue封装自定义指令之动态显示title操作(溢出显示,不溢出不显示),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • vue实现换肤功能

    vue实现换肤功能

    这篇文章主要为大家详细介绍了vue实现换肤功能,一套深色,一套浅色,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Vue.use()和Vue.prototype使用详解

    Vue.use()和Vue.prototype使用详解

    Vue.use()主要用于注册全局插件,当插件具有install方法时,调用Vue.use()可以全局使用该插件,Vue.prototype用于注册全局变量,这些变量在项目任何位置都可以通过this.$变量名访问,两者的主要区别在于Vue.use()用于插件,Vue.prototype用于变量
    2024-10-10
  • 聊聊Vue中provide/inject的应用详解

    聊聊Vue中provide/inject的应用详解

    这篇文章主要介绍了聊聊Vue中provide/inject的应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 一文带你了解什么是Vue Vapor

    一文带你了解什么是Vue Vapor

    随着Svelte和SolidJS的流行,无虚拟DOM模式逐渐开始火了起来,Vue Vapor就是一个无虚拟DOM模式版本的vue,下面就跟随小编一起来深入了解一下Vue Vapor吧
    2024-11-11
  • vue中的ElementUI的使用详解

    vue中的ElementUI的使用详解

    本文通过实例代码给大家介绍了vue中的ElementUI的使用,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • 浅析从面向对象思维理解Vue组件

    浅析从面向对象思维理解Vue组件

    用面向对象的思维去理解Vue组件,可以将所有的事物都抽象为对象,而类或者说是组件,都具有属性和操作。这篇文章主要介绍了尝试用面向对象思维理解Vue组件,需要的朋友可以参考下
    2021-07-07
  • Vue3源码解读computed和watch

    Vue3源码解读computed和watch

    这篇文章主要为大家介绍了Vue3中的computed和watch源码解读分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Vue获取微博授权URL代码实例

    Vue获取微博授权URL代码实例

    这篇文章主要介绍了Vue获取微博授权URL代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11

最新评论