详解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随便控制任意div隐藏的方法
Jun 28 Javascript
JS 对输入框进行限制(常用的都有)
Jul 30 Javascript
jQuery绑定事件不执行但alert后可以正常执行
Jun 03 Javascript
javascript中判断json的方法总结
Aug 27 Javascript
在React框架中实现一些AngularJS中ng指令的例子
Mar 06 Javascript
javascript实现任务栏消息提示的简单实例
May 31 Javascript
JS Ajax请求如何防止重复提交
Jun 13 Javascript
jQuery Ajax传值到Servlet出现乱码问题的解决方法
Oct 09 Javascript
基于Node.js实现压缩和解压缩的方法
Feb 13 Javascript
微信小程序实现星星评价效果
Nov 02 Javascript
vue 使用post/get 下载导出文件操作
Aug 07 Javascript
JavaScript 如何在浏览器中使用摄像头
Dec 02 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/07/02 PHP
session在php5.3中的变化 session_is_registered() is deprecated in
2013/11/12 PHP
thinkphp中memcache的用法实例
2014/11/29 PHP
Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法
2016/05/31 PHP
php投票系统之增加与删除投票(管理员篇)
2016/07/01 PHP
详解PHP中的外观模式facade pattern
2018/02/05 PHP
laravel 验证错误信息到 blade模板的方法
2019/09/29 PHP
Nigma vs Alliance BO5 第五场2.14
2021/03/10 DOTA
jquery判断单个复选框是否被选中的代码
2009/09/03 Javascript
JavaScript 继承机制的实现(待续)
2010/05/18 Javascript
Tips 带三角可关闭的文字提示
2010/10/06 Javascript
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
Jquery动态更改一张位图的src与Attr的使用
2013/07/31 Javascript
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
2014/08/30 Javascript
jQuery表格插件datatables用法总结
2014/09/05 Javascript
一个非常好用的文字滚动的案例,鼠标悬浮可暂停[两种方案任选]
2016/12/01 Javascript
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
2017/10/19 jQuery
通过js实现压缩图片上传功能
2020/02/25 Javascript
文章或博客自动生成章节目录索引(支持三级)的实现代码
2020/05/10 Javascript
ant design vue datepicker日期选择器中文化操作
2020/10/28 Javascript
[01:31](回顾)杀出重围,决战TI之巅
2014/07/01 DOTA
python中尾递归用法实例详解
2015/04/28 Python
Python实现网站表单提交和模板
2019/01/15 Python
Python OpenCV 调用摄像头并截图保存功能的实现代码
2019/07/02 Python
PyCharm第一次安装及使用教程
2020/01/08 Python
使用Python获取当前工作目录和执行命令的位置
2020/03/09 Python
html5弹跳球示例代码
2013/07/23 HTML / CSS
HTML5实现签到 功能
2018/10/09 HTML / CSS
入党自我评价优缺点
2014/01/25 职场文书
总裁助理岗位职责
2014/02/17 职场文书
材料工程专业毕业生求职信
2014/03/04 职场文书
爱国主义演讲稿
2014/05/07 职场文书
主题班会演讲稿
2014/05/22 职场文书
入党积极分子党支部意见
2015/06/02 职场文书
Python办公自动化之Excel(中)
2021/05/24 Python
Apache SkyWalking 监控 MySQL Server 实战解析
2022/09/23 Servers