详解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 学习笔记之一jQuery写法图片等比缩放以及预加载
Jun 28 Javascript
让低版本浏览器支持input的placeholder属性(js方法)
Apr 03 Javascript
jquery自定义属性(类型/属性值)
May 21 Javascript
jQuery中$(function() {});问题详解
Aug 10 Javascript
js+div实现文字滚动和图片切换效果代码
Aug 27 Javascript
基于RequireJS和JQuery的模块化编程日常问题解析
Apr 14 Javascript
BootStrap 附加导航组件
Jul 22 Javascript
JQuery统计input和textarea文字输入数量(代码分享)
Dec 29 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
Mar 03 Javascript
Vue不能观察到数组length的变化
Jun 08 Javascript
关于单文件组件.vue的使用
Sep 20 Javascript
如何在JavaScript中创建具有多个空格的字符串?
Feb 23 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变量作用域的深入解析
2013/06/03 PHP
php实现的获取网站备案信息查询代码(360)
2013/09/23 PHP
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
js实现对table动态添加、删除和更新的方法
2015/02/10 Javascript
jQuery+AJAX实现网页无刷新上传
2015/02/22 Javascript
jquery动态导航插件dynamicNav用法实例分析
2015/09/06 Javascript
JS模拟酷狗音乐播放器收缩折叠关闭效果代码
2015/10/29 Javascript
基于javascript html5实现3D翻书特效
2016/03/14 Javascript
改变checkbox默认选中状态及取值的实现代码
2016/05/26 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
2017/03/15 Javascript
Js实现中国公民身份证号码有效性验证实例代码
2017/05/03 Javascript
用js将long型数据转换成date型或datetime型的实例
2017/07/03 Javascript
JS+HTML5实现获取手机验证码倒计时按钮
2018/08/08 Javascript
解决vue打包css文件中背景图片的路径问题
2018/09/03 Javascript
详解Element 指令clickoutside源码分析
2019/02/15 Javascript
jQuery实现数字华容道小游戏(实例代码)
2020/01/16 jQuery
JS实现简易计算器
2020/02/14 Javascript
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
python requests爬取高德地图数据的实例
2018/11/10 Python
django Admin文档生成器使用详解
2019/07/22 Python
Python垃圾回收机制三种实现方法
2020/04/27 Python
pycharm 如何取消连按两下shift出现的全局搜索
2021/01/15 Python
Python Selenium破解滑块验证码最新版(GEETEST95%以上通过率)
2021/01/29 Python
HTML5 本地存储 LocalStorage详解
2016/06/24 HTML / CSS
说出一些常用的类,包,接口
2014/09/22 面试题
求职简历中个人的自我评价
2013/12/01 职场文书
《英英学古诗》教学反思
2014/04/11 职场文书
企业宣传工作方案
2014/06/02 职场文书
2014年小班保育员工作总结
2014/12/23 职场文书
2015年感恩父亲节演讲稿
2015/03/19 职场文书
婚礼迎宾词大全
2015/08/10 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
廉洁自律承诺书2016
2016/03/25 职场文书
慰问信的写作格式及范文!
2019/06/24 职场文书
python实现自动化群控的步骤
2021/04/11 Python
MySQL常见优化方案汇总
2022/01/18 MySQL