详解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 相关文章推荐
一段实时更新的时间代码
Jul 07 Javascript
两种方法实现文本框输入内容提示消失
Mar 17 Javascript
JS实现时间格式化的方式汇总
Oct 16 Javascript
JQueryiframe页面操作父页面中的元素与方法(实例讲解)
Nov 19 Javascript
通过JS来判断页面控件是否获取焦点
Jan 03 Javascript
JQuery标签页效果实例详解
Dec 24 Javascript
基于js中的原型、继承的一些想法
Aug 10 Javascript
浅谈在js传递参数中含加号(+)的处理方式
Oct 11 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
Jan 30 Javascript
详解angular脏检查原理及伪代码实现
Jun 08 Javascript
使用elementUI实现将图片上传到本地的示例
Sep 04 Javascript
详解JS深拷贝与浅拷贝
Aug 04 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
GD输出汉字的函数的分析
2006/10/09 PHP
PHP获取数组中重复最多的元素的实现方法
2014/11/11 PHP
WordPress主题中添加文章列表页页码导航的PHP代码实例
2015/12/22 PHP
Add a Picture to a Microsoft Word Document
2007/06/15 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
2013/08/14 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
2015/04/17 Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
2016/09/01 Javascript
详解javascript事件绑定使用方法
2016/10/20 Javascript
js处理层级数据结构的方法小结
2017/01/17 Javascript
Node.js查找当前目录下文件夹实例代码
2017/03/07 Javascript
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
Angular7中创建组件/自定义指令/管道的方法实例详解
2019/04/02 Javascript
解决vue中使用proxy配置不同端口和ip接口问题
2019/08/14 Javascript
Net微信网页开发 使用微信JS-SDK获取当前地理位置过程详解
2019/08/26 Javascript
vue+layui实现select动态加载后台数据的例子
2019/09/20 Javascript
Vue实现简单计算器案例
2020/02/25 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
Vue axios 跨域请求无法带上cookie的解决
2020/09/08 Javascript
Python实现全角半角字符互转的方法
2016/11/28 Python
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
利用信号如何监控Django模型对象字段值的变化详解
2017/11/27 Python
python3+PyQt5自定义视图详解
2018/04/24 Python
Python读取本地文件并解析网页元素的方法
2018/05/21 Python
python实现五子棋小程序
2019/06/18 Python
django中related_name的用法说明
2020/05/20 Python
Django如何继承AbstractUser扩展字段
2020/11/27 Python
python pyg2plot的原理知识点总结
2021/02/28 Python
CSS3五个技巧给你的网站带来出色的效果
2009/04/02 HTML / CSS
美国最大的香水出口:FragranceX.com
2017/11/04 全球购物
Pam & Gela官网:美国性感前卫女装品牌
2018/07/19 全球购物
运输服务质量承诺书
2014/03/27 职场文书
弘扬雷锋精神演讲稿
2014/05/10 职场文书
英语三分钟演讲稿
2014/08/19 职场文书
2015年安康杯竞赛活动总结
2015/03/26 职场文书
python全面解析接口返回数据
2022/02/12 Python
MySQL如何快速创建800w条测试数据表
2022/03/17 MySQL