详解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 TO HTML 转换
Jun 26 Javascript
showModelessDialog()使用详解
Sep 21 Javascript
让你的网站可编辑的实现js代码
Oct 19 Javascript
jquery的extend和fn.extend的使用说明
Jan 09 Javascript
最常用的12种设计模式小结
Aug 09 Javascript
JS预览图像将本地图片显示到浏览器上
Aug 25 Javascript
微信小程序中使元素占满整个屏幕高度实现方法
Dec 14 Javascript
微信小程序 封装http请求实例详解
Jan 16 Javascript
JS实现DIV高度自适应窗口示例
Feb 16 Javascript
jQuery实现的表格前端排序功能示例
Sep 18 jQuery
js技巧之十几行的代码实现vue.watch代码
Jun 09 Javascript
用Javascript实现发送短信验证码间隔功能
Feb 08 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 生成饼图 三维饼图
2009/09/28 PHP
php从右向左/从左向右截取字符串的实现方法
2011/11/28 PHP
php二维数组排序方法(array_multisort usort)
2013/12/25 PHP
nodejs中实现sleep功能实例
2015/03/24 NodeJs
详解JavaScript中void语句的使用
2015/06/04 Javascript
js的flv视频播放器插件使用方法
2015/06/23 Javascript
JavaScript使表单中的内容显示在屏幕上的方法
2015/06/29 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
AngularJs页面筛选标签小功能
2016/08/01 Javascript
详解javascript表单的Ajax提交插件的使用
2016/12/29 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
微信小程序实现slideUp、slideDown滑动效果及点击空白隐藏功能示例
2018/12/11 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
2019/09/05 Javascript
[05:06]DOTA2-DPC中国联赛 正赛 VG vs Magma选手采访
2021/03/11 DOTA
Python字符串替换实例分析
2015/05/11 Python
Python编写电话薄实现增删改查功能
2016/05/07 Python
python批量制作雷达图的实现方法
2016/07/26 Python
Python可变参数*args和**kwargs用法实例小结
2018/04/27 Python
python Web开发你要理解的WSGI &amp; uwsgi详解
2018/08/01 Python
对python csv模块配置分隔符和引用符详解
2018/12/12 Python
Django框架下静态模板的继承操作示例
2019/11/08 Python
为什么黑客都用python(123个黑客必备的Python工具)
2020/01/31 Python
python中@property的作用和getter setter的解释
2020/12/22 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
名人珠宝设计师:Melinda Maria Jewelry
2019/03/06 全球购物
Brora官网:英国领先的羊绒服装品牌
2019/08/28 全球购物
大学生专科毕业生自我评价
2013/11/17 职场文书
挂牌仪式策划方案
2014/05/18 职场文书
建筑工地大门标语
2014/06/18 职场文书
应届生面试求职信
2014/07/02 职场文书
防邪知识进家庭活动方案
2014/08/26 职场文书
工人先锋号事迹材料
2014/12/24 职场文书
大学生各类奖学金申请书
2019/06/24 职场文书
最新的离婚协议书范本!
2019/07/02 职场文书
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python
nginx刷新页面出现404解决方案(亲测有效)
2022/03/18 Servers