详解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函数的等价原生函数代码示例
May 27 Javascript
js循环改变div颜色具体方法
Jun 25 Javascript
JavaScript+CSS控制打印格式示例介绍
Jan 07 Javascript
Linux下编译安装php libevent扩展实例
Feb 14 Javascript
JS实现的简洁二级导航菜单雏形效果
Oct 13 Javascript
JavaScript简单生成 N~M 之间随机数的方法
Jan 13 Javascript
javaScript封装的各种写法
Aug 14 Javascript
Vue 项目代理设置的优化
Apr 17 Javascript
vue2.0项目实现路由跳转的方法详解
Jun 21 Javascript
通过实例学习React中事件节流防抖
Jun 17 Javascript
webpack 如何解析代码模块路径的实现
Sep 04 Javascript
Vue3.0 响应式系统源码逐行分析讲解
Oct 14 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
jQuery EasyUI API 中文文档 - DateBox日期框
2011/10/15 PHP
Thinkphp 中 distinct 的用法解析
2016/12/14 PHP
Jquery知识点二 jquery下对数组的操作
2011/01/15 Javascript
节点的插入之append()和appendTo()的用法介绍
2014/01/13 Javascript
通过遮罩层实现浮层DIV登录的js代码
2014/02/07 Javascript
jQuery CSS()方法改变现有的CSS样式
2014/08/20 Javascript
ZeroClipboard插件实现多浏览器复制功能(支持firefox、chrome、ie6)
2014/08/30 Javascript
jQuery扁平化风格下拉框美化插件FancySelect使用指南
2015/02/10 Javascript
JavaScript生成SQL查询表单的方法
2015/08/13 Javascript
js实现无限级树形导航列表效果代码
2015/09/23 Javascript
JavaScript 消息框效果【实现代码】
2016/04/27 Javascript
用jquery获取自定义的标签属性的值简单实例
2016/09/17 Javascript
Nodejs进阶:如何将图片转成datauri嵌入到网页中去实例
2016/11/21 NodeJs
ES6(ECMAScript 6)新特性之模板字符串用法分析
2017/04/01 Javascript
详解webpack异步加载业务模块
2017/06/23 Javascript
详解在vue-cli项目中使用mockjs(请求数据删除数据)
2017/10/23 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
angularjs手动识别字符串中的换行符方法
2018/10/02 Javascript
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
小程序如何支持使用 async/await详解
2019/09/12 Javascript
JS实现单张或多张图片持续无缝滚动的示例代码
2020/05/10 Javascript
vue select 获取value和lable操作
2020/08/28 Javascript
[02:32]DOTA2完美大师赛场馆静安体育中心观赛全攻略
2017/11/08 DOTA
python利用Guetzli批量压缩图片
2017/03/23 Python
Python使用Matlab命令过程解析
2020/06/04 Python
Python实现http接口自动化测试的示例代码
2020/10/09 Python
Python爬虫定时计划任务的几种常见方法(推荐)
2021/01/15 Python
新加坡最佳婴儿用品店:Mamahood.com.sg
2018/08/26 全球购物
Haglöfs瑞典官方网站:haglofs火柴棍,欧洲顶级户外品牌
2018/10/18 全球购物
木马的传播途径主要有哪些
2016/04/08 面试题
拉丁舞学习者的自我评价
2013/10/27 职场文书
倡议书范文
2014/04/16 职场文书
幼儿园中班区域活动总结
2014/07/09 职场文书
2014年群众路线党员自我评议
2014/09/24 职场文书
会计岗位职责范本
2015/04/02 职场文书
python 中[0]*2与0*2的区别说明
2021/05/10 Python