详解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 相关文章推荐
js类后台管理菜单类-MenuSwitch
Sep 12 Javascript
javascript 计算两个整数的百分比值
Dec 26 Javascript
当自定义数据属性为json格式字符串时jQuery的data api问题探讨
Feb 18 Javascript
node.js中的fs.readSync方法使用说明
Dec 17 Javascript
Javascript简单改变表单元素背景的方法
Jul 15 Javascript
JavaScript编程中的Promise使用大全
Jul 28 Javascript
javascript针对cookie的基本操作实例详解
Nov 30 Javascript
微信小程序实现倒计时60s获取验证码
Apr 17 Javascript
浅谈使用React.setState需要注意的三点
Dec 18 Javascript
JavaScript高级函数应用之分时函数实例分析
Aug 03 Javascript
移动端手指操控左右滑动的菜单
Sep 08 Javascript
vue 解决无法对未定义的值,空值或基元值设置反应属性报错问题
Jul 31 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
php 5.3.5安装memcache注意事项小结
2011/04/12 PHP
php标签云的实现代码
2012/10/10 PHP
采用ThinkPHP中F方法实现快速缓存实例
2014/06/13 PHP
PHP中OpenSSL加密问题整理
2017/12/14 PHP
PHP7.1实现的AES与RSA加密操作示例
2018/06/15 PHP
windows系统php环境安装swoole具体步骤
2021/03/04 PHP
获取Javscript执行函数名称的方法
2006/12/22 Javascript
Javascript实例教程(19) 使用HoTMetal(6)
2006/12/23 Javascript
Javascript面向对象扩展库代码分享
2012/03/27 Javascript
js获取客户端外网ip的简单实例
2013/11/21 Javascript
js返回上一页并刷新的多种实现方法
2014/02/26 Javascript
js插件YprogressBar实现漂亮的进度条效果
2015/04/20 Javascript
Bootstrap按钮组件详解
2016/04/26 Javascript
解析JavaScript中的字符串类型与字符编码支持
2016/06/24 Javascript
jQuery插件DataTables分页开发心得体会
2017/08/22 jQuery
vuex的module模块用法示例
2018/11/12 Javascript
vue通过video.js解决m3u8视频播放格式的方法
2019/07/30 Javascript
微信小程序iBeacon测距及稳定程序的实现解析
2019/07/31 Javascript
微信小程序 子级页面返回父级并把子级参数带回父级实现方法
2019/08/22 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
2021/01/20 Vue.js
[00:31]DOTA2上海特级锦标赛 Fnatic战队宣传片
2016/03/04 DOTA
使用python实现省市三级菜单效果
2016/01/20 Python
Python根据指定日期计算后n天,前n天是哪一天的方法
2018/05/29 Python
用Python识别人脸,人种等各种信息
2019/07/15 Python
python requests指定出口ip的例子
2019/07/25 Python
elasticsearch python 查询的两种方法
2019/08/04 Python
python中@property和property函数常见使用方法示例
2019/10/21 Python
python连接手机自动搜集蚂蚁森林能量的实现代码
2021/02/24 Python
css3学习之2D转换功能详解
2016/12/23 HTML / CSS
创先争优活动方案
2014/02/12 职场文书
家长会主持词
2014/03/26 职场文书
2014年社区妇联工作总结
2014/12/02 职场文书
求职自我评价怎么写
2015/03/09 职场文书
2015年大学生入党自荐书
2015/03/24 职场文书
python 如何用map()函数创建多线程任务
2021/04/07 Python
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS