详解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 相关文章推荐
基于jquery css3实现点击动画弹出表单源码特效
Aug 31 Javascript
js将滚动条滚动到指定位置的简单实现方法
Jun 25 Javascript
详谈js中window.location.search的用法和作用
Feb 13 Javascript
Node.js服务器开启Gzip压缩教程
Aug 11 Javascript
详解各版本React路由的跳转的方法
May 10 Javascript
jQuery中元素选择器(element)简单用法示例
May 14 jQuery
vue视频播放暂停代码
Nov 08 Javascript
详解微信小程序中var、let、const用法与区别
Jan 11 Javascript
Js生成随机数/随机字符串的方法小结【5种方法】
May 27 Javascript
解决Vue + Echarts 使用markLine标线(precision精度问题)
Jul 20 Javascript
Vue实现点击当前行变色
Dec 14 Vue.js
ajax jquery实现页面某一个div的刷新效果
Mar 04 jQuery
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
我常用的几个类
2006/10/09 PHP
PHP 在线翻译函数代码
2009/05/07 PHP
Linux系统下使用XHProf和XHGui分析PHP运行性能
2015/12/08 PHP
PHP 二维数组和三维数组的过滤
2016/03/16 PHP
PHP框架自动加载类文件原理详解
2017/06/06 PHP
Laravel框架控制器,视图及模型操作图文详解
2019/12/04 PHP
dess中一个简单的多路委托的实现
2010/07/20 Javascript
JS中attr和prop属性的区别以及优先选择示例介绍
2014/06/30 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
详细讲解JavaScript中的this绑定
2016/10/10 Javascript
JavaScrpt判断一个数是否是质数的实例代码
2017/06/11 Javascript
在一个页面实现两个zTree联动的方法
2017/12/20 Javascript
JS和Canvas实现图片的预览压缩和上传功能
2018/03/30 Javascript
浅谈webpack-dev-server的配置和使用
2018/05/17 Javascript
video.js 一个页面同时播放多个视频的实例代码
2018/11/27 Javascript
layui表单提交到后台自动封装到实体类的方法
2019/09/12 Javascript
简单了解Vue + ElementUI后台管理模板
2020/04/07 Javascript
构建一个JavaScript插件系统
2020/10/20 Javascript
Python访问MySQL封装的常用类实例
2014/11/11 Python
详解python之简单主机批量管理工具
2017/01/27 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
2018/08/02 Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
2019/01/04 Python
python 实现视频流下载保存MP4的方法
2019/01/09 Python
对python条件表达式的四种实现方法小结
2019/01/30 Python
对Python中class和instance以及self的用法详解
2019/06/26 Python
Django Rest framework认证组件详细用法
2019/07/25 Python
Python 限定函数参数的类型及默认值方式
2019/12/24 Python
pycharm安装及如何导入numpy
2020/04/03 Python
Python文件名匹配与文件复制的实现
2020/12/11 Python
捷克体育用品购物网站:D-sport
2017/12/28 全球购物
学习心得体会
2014/01/01 职场文书
幼儿园毕业寄语
2014/04/03 职场文书
拒绝黄毒毒宣传标语
2014/06/26 职场文书
个人委托函范文
2015/01/29 职场文书
2015年保险业务员工作总结
2015/05/27 职场文书
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js