详解vue 自定义marquee无缝滚动组件


Posted in Javascript onApril 09, 2019

先上效果图:

详解vue 自定义marquee无缝滚动组件

(1) 看起来可能有点卡顿,但是实际上页面上看起来挺顺畅的。

(2) 思路就是获取每一个列表的宽度,设置定时器移动列表,当移动的距离达到一个列表的宽度的时候,把这个距离放到数组的最后。这样就能达成无缝循环滚动了。

 大致的情况就是下面这样:

 详解vue 自定义marquee无缝滚动组件

接下来就是代码的实现:

index.vue 引入组件

<template>
 <div>
  <marqueeLeft :send-val='send'></marqueeLeft >
 </div>
</template>
<script>
 import marqueeLeft from '../components/marquee'
 export default {
  data:function(){
   return{
    send:[{place: "来自东莞市的", name: "黄女士"},
   {place: "来自太原市的", name: "吴先生"},
   {place: "来自常州市的", name: "戚先生"},
   {place: "来自金华市的", name: "尤先生"},
   {place: "来自贵阳市的", name: "陈女士"},
   {place: "来自长春市的", name: "魏女士"},
   {place: "来自泉州市的", name: "褚先生"},
   {place: "来自南昌市的", name: "蒋女士"},
   {place: "来自南京市的", name: "沈先生"},
   {place: "来自天津市的", name: "韩先生"},
   {place: "来自宁波市的", name: "邹女士"},
   {place: "来自嘉兴市的", name: "周女士"},
   {place: "来自长沙市的", name: "秦先生"},
   {place: "来自济南市的", name: "孙女士"},
   {place: "来自杭州市的", name: "杨先生"}]
   }
  },
  components:{ marqueeLeft },
 }
</script>

marquee.vue 组件页面

<template>
 <div class="my-outbox">
  <div class="my-inbox" ref='box'>
   <div class="my-list" v-for="(item,index) in sendVal" :key='index' ref='list'>
    {{item.place}}<span class="my-uname">{{item.name}}</span>刚刚购买了产品
   </div>
  </div>
 </div>
</template>

<script>
 export default {
  name:'my-marquee-left',
  props:{  
   sendVal:Array
  },
  data() {
   return {
    nowTime:null,//定时器标识
    disArr:[],//每一个内容的宽度
   }
  }, 
  mounted:function(){
   var that = this;
   var item = this.$refs.list; 
   var len = this.sendVal.length;
   var arr = [];
   var margin = this.getMargin(item[0]) //因为设置的margin值一样,所以取第一个就行。
   for(var i = 0;i < len;i++){
    arr.push(item[i].clientWidth + margin)//把宽度和 margin 加起来就是每一个元素需要移动的距离
   }
   this.disArr = arr;
   this.moveLeft();
  },
  beforeDestroy:function(){
   clearInterval(this.nowTime);//页面关闭清除定时器
   this.nowTime = null;//清除定时器标识
  },
  methods:{
   //获取margin属性
   getMargin:function(obj){
    var marg = window.getComputedStyle(obj,null)['margin-right'];
    marg = marg.replace('px','')
    return Number(marg) //强制转化成数字
   },
   //移动的方法
   moveLeft:function(){
    var outbox = this.$refs.box;
    var that=this;
    var startDis = 0;//初始位置
    this.nowTime = setInterval(function(){
     startDis -= 0.5;
     if(Math.abs(startDis) > Math.abs(that.disArr[0])){
      that.disArr.push(that.disArr.shift())//每次移动完一个元素的距离,就把这个元素的宽度
      that.sendVal.push(that.sendVal.shift())//每次移动完一个元素的距离,就把列表数据的第一项放到最后一项
      startDis = 0;
     }
     outbox.style = 'transform: translateX('+ startDis +'px)'; //每次都让盒子移动指定的距离
    },1000/60)
   }
  }
 }
</script>

<style lang="less" scoped>
 .my-outbox{
  color: #D7BC8D;
  overflow: hidden;
  height: 35px;
  background: #422b02;
  .my-inbox{
   white-space: nowrap;
   .my-list{
    margin-right: 25px;
    display: inline-block;
    font-size: 13px;
    height: 35px;
    line-height: 35px;
    .my-uname{
     color: #FF8900;
    }
   }
  }
 }
</style>

(1) 添加一个获取margin的方法,是为了保证如果是使用 rem em 等单位时,margin值不会出现偏差的情况

(2) 如果引入组件的页面中,send-val的值是异步请求的。那么,在marquee.vue组件页面,多数情况会获取不了 refs 。这时候我自己的解决方法是:

<marqueeLeft :send-val='send' v-if='send'></marqueeLeft >

 表示只有当 send 不为空的时候才渲染该组件,不过这种情况会导致如果 请求响应太慢,组件会一直渲染不出来,就可能会影响布局。

(3) 如果不想每次都去设置transform,那么可以把transform放到该元素上,然后修改data中的数据就行了,比如:

<div class="my-inbox" :style='transform: translateX('+ cssStyle +'px)'></div>
// 然后在 js 中把 每次移动的值,赋值给cssStyle就行了。不过我感觉这种没什么区别

 如果想实现,上下无缝滚动,这种效果。思路和左右无缝滚动一样,基本上只需要把 transform 改成 Y轴移动 ,每个列表的宽度改成高度就行了。

不清楚这种方式实现是否会有什么问题,FPS一直保持在 接近60左右。暂时没发现什么缺点。。。

以上所述是小编给大家介绍的vue自定义marquee无缝滚动组件详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Javascript学习笔记2 函数
Jan 11 Javascript
javascript学习笔记(十二) RegExp类型介绍
Jun 20 Javascript
jquery默认校验规则整理
Mar 24 Javascript
javascript获取flash版本号的方法
Nov 20 Javascript
javascript中加var和不加var的区别 你真的懂吗
Jan 06 Javascript
bootstrap table动态加载数据示例代码
Mar 25 Javascript
(模仿京东用户注册)用JQuery实现简单表单验证,初学者必看
Jan 08 jQuery
JavaScript闭包原理与用法实例分析
Aug 10 Javascript
解决vue 打包发布去#和页面空白的问题
Sep 04 Javascript
vue-cli监听组件加载完成的方法
Sep 07 Javascript
JavaScript对象拷贝与赋值操作实例分析
Dec 10 Javascript
详解Vue-cli3 项目在安卓低版本系统和IE上白屏问题解决
Apr 14 Javascript
javascript实现手动点赞效果
Apr 09 #Javascript
实例分析Array.from(arr)与[...arr]到底有何不同
Apr 09 #Javascript
浅谈Vue.js组件(二)
Apr 09 #Javascript
4 种滚动吸顶实现方式的比较
Apr 09 #Javascript
vue响应式系统之observe、watcher、dep的源码解析
Apr 09 #Javascript
浅谈发布订阅模式与观察者模式
Apr 09 #Javascript
vue使用keep-alive保持滚动条位置的实现方法
Apr 09 #Javascript
You might like
推荐一款MAC OS X 下php集成开发环境mamp
2014/11/08 PHP
CI框架集成Smarty的方法分析
2016/05/17 PHP
PHP hex2bin()函数用法讲解
2019/02/25 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
2020/02/12 PHP
将光标定位于输入框最右侧实现代码
2012/12/04 Javascript
利用js判断浏览器类型(是否为IE,Firefox,Opera浏览器)
2013/11/22 Javascript
js propertychange和oninput事件
2014/09/28 Javascript
jQuery对象与DOM对象之间的相互转换
2015/03/03 Javascript
JavaScript中匿名函数用法实例
2015/03/23 Javascript
jquery拖拽效果完整实例(附demo源码下载)
2016/01/14 Javascript
AngularJS基础 ng-copy 指令实例代码
2016/08/01 Javascript
jquery 动态增加删除行的简单实例(推荐)
2016/10/12 Javascript
浅析JS中的 map, filter, some, every, forEach, for in, for of 用法总结
2017/03/29 Javascript
Angularjs中的验证input输入框只能输入数字和小数点的写法(推荐)
2017/08/16 Javascript
ES6关于Promise的用法详解
2018/05/07 Javascript
Echarts实现单条折线可拖拽效果
2019/12/19 Javascript
[05:07]DOTA2英雄梦之声_第14期_暗影恶魔
2014/06/20 DOTA
[00:58]他们到底在电话里听到了什么?
2017/11/21 DOTA
Zabbix实现微信报警功能
2016/10/09 Python
Python import与from import使用及区别介绍
2018/09/06 Python
python 寻找离散序列极值点的方法
2019/07/10 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
2019/09/10 Python
python集合的创建、添加及删除操作示例
2019/10/08 Python
Python 读取位于包中的数据文件
2020/08/07 Python
python xlsxwriter模块的使用
2020/12/24 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
如何打造一封优秀的留学推荐信
2014/01/25 职场文书
网吧最新创业计划书范文
2014/03/27 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
市场调研项目授权委托书范本
2014/10/04 职场文书
高中校园广播稿
2014/10/21 职场文书
硕士论文致谢范文
2015/05/14 职场文书
党员证明模板
2015/06/19 职场文书
环保主题班会教案
2015/08/13 职场文书
上帝为你开了一扇窗之Tkinter常用函数详解
2021/06/02 Python
解决Mysql中的innoDB幻读问题
2022/04/29 MySQL