写插件的初衷

1.项目经常需要无缝滚动效果,当时写jq的时候用用msClass这个老插件,相对不上很好用。

2.后来转向vue在vue-awesome没有找到好的无缝滚动插件,除了配置swiper可以实现但是相对来说太重了,于是自己造了个轮子。

3.在这分享下,当时写这个插件的坑,自己也复习下,如果代码上有瑕疵欢迎指出。

源码参考 vue-seamless-scroll

1.简单的实现上下滚动基本版(最初版)

html

1.solt提供默认插槽位来放置父组件传入的html

<template><div @mouseenter="enter" @mouseleave="leave"><div ref="wrapper" :style="pos"><slot></slot></div></div>
</template>
复制代码

javascript

1.animationFrame 动画api兼容处理

2.arrayEqual 判断数组是否相等 来监听data的变化来实现更新无缝滚动

<script>require('comutils/animationFrame')  //requestAnimationFrame apiconst arrayEqual = require('comutils/arrayEqual')export default {data () {return {yPos: 0,reqFrame: null}},props: {data: { // data 数据type: Array,default: []},classOption: { //参数type: Object,default: {}}},computed: {pos () {// 给父元素的stylereturn {transform: `translate(0,${this.yPos}px)`}},defaultOption () {return {step: 1, //步长limitMoveNum: 5, //启动无缝滚动最小数据数hoverStop: true, //是否启用鼠标hover控制direction: 1 //1 往上 0 往下}},options () {// 合并参数return Object.assign({}, this.defaultOption, this.classOption)},moveSwitch () {//判断传入的初始滚动值和data的length来控制是否滚动return this.data.length < this.options.limitMoveNum}},methods: {enter () {if (!this.options.hoverStop || this.moveSwitch) returncancelAnimationFrame(this.reqFrame)},leave () {if (!this.options.hoverStop || this.moveSwitch) returnthis._move()},_move () {//滚动this.reqFrame = requestAnimationFrame(() => {let h = this.$refs.wrapper.offsetHeight / 2let direction = this.options.directionif (direction === 1) {if (Math.abs(this.yPos) >= h) this.yPos = 0} else {if (this.yPos >= 0) this.yPos = h * -1}if (direction === 1) {this.yPos -= this.options.step} else {this.yPos += this.options.step}this._move()})},_initMove () {if (this.moveSwitch) {cancelAnimationFrame(this.reqFrame)this.yPos = 0} else {this.$emit('copyData') //需要copy复制一份 emit到父元素  后期版本这里已经优化if (this.options.direction !== 1) {setTimeout(() => {this.yPos = this.$refs.wrapper.offsetHeight / 2 * -1}, 20)}this._move()}}},mounted () {this._initMove()},watch: {//监听data的变化data (newData, oldData) {if (!arrayEqual(newData, oldData.concat(oldData))) {cancelAnimationFrame(this.reqFrame)this._initMove()}}}}
</script>
复制代码

1.1 优化1: 新增配置openWatch 是否开启data监控实时刷新

有兴趣可以看本次commit记录 myClass.vue的更改

1.2 优化2: 新增配置singleHeight waitTime参数 控制是否单步滚动

commit记录

1.3 优化3:添加对移动端touch事件滚动列表支持

commit记录

1.4 优化4: 去掉了emit回调(简化初始化)

//原本组件调用
<my-class :data="listData" :class-option="classOption" @copy-data="listData = listData.concat(listData)">
//简化后组件调用
<my-class :data="listData" :class-option="classOption" class="warp">
复制代码
用js的来复制一份innerHtml来代替之前的做法简化使用
//this.$emit('copyData')timer = setTimeout(() => { //20ms延迟 作用保证能取到最新的htmlthis.copyHtml = this.$refs.slotList.innerHTML}, 20)// template<template><div @mouseenter="enter" @mouseleave="leave" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"><div ref="wrap" :style="pos"><div ref="slotList" :style="float"><slot></slot></div><div v-html="copyHtml" :style="float"></div></div></div>
</template>
复制代码

commit记录

1.5 bug1: 解决ie9下animationFrame报错的bug

这个问题的原因查了比较久最后发现是当时没有加return没有取到定时器id

1.6 优化5:添加左右无缝滚动

类似上下可以查看commit

1.7 Vue.use() 提供install全局注册

import vueMyCLass from './components/myClass.vue'let myScrollconst defaultComponentName = 'vue-seamless-scroll'// expose component to global scope
if (typeof window !== 'undefined' && window.Vue) {Vue.component('vue-seamless-scroll', vueMyCLass)
} else {myScroll = {install: function (Vue, options = {}) {Vue.component(options.componentName || defaultComponentName, vueMyCLass)}}}export default myScroll
复制代码

1.8 bug 解决了touchMove频繁快速操作导致单步滚动失效bug 和部分代码优化

//1.封装多次调用的取消动画方法

_cancle: function _cancle() {cancelAnimationFrame(this.reqFrame || '');},
复制代码

//2.touchMove频繁快速操作导致滚动错乱bug

 _move () {this._cancle() //进入move立即先清除动画 防止频繁touchMove导致多动画同时进行}
复制代码

//3.生命周期结束前取消动画

 beforeDestroy () {this._cancle()
}
复制代码

//4.修复不传参数报警告的bug

 props: {data: {type: Array,default: () => {return []}},classOption: {type: Object,default: () => {return {}}}}
复制代码

//5.Fixing a bug. add a overflow:hidden on the child element

部分人喜欢用margin-top如果没有overflow等限制会导致我里面计算高度和实际有些许差距导致最后效果到临界位置有轻微抖动 //默认加上了overflow: 'hidden'

computed: {float () {return this.options.direction > 1 ? {float: 'left', overflow: 'hidden'} : {overflow: 'hidden'}},pos () {return {transform: `translate(${this.xPos}px,${this.yPos}px)`,transition: `all ease-in ${this.delay}ms`,overflow: 'hidden'}}
}
复制代码

//6.新增单步滚动也能hover停止的功能

之前因为单步滚动内置了延迟执行this._move()默认单步限制了鼠标悬停停止无缝滚动,后来通过给this._move()加上开关达到效果。

commit

TKS

如果对原生js实现类似的无缝滚动有兴趣可以留言,我抽空也可以写下seamless-scroll

vue-seamless-scroll发现bug或者有什么不足望指点,感觉不错点个star吧。

转载于:https://juejin.im/post/5a6b266851882573402677b9

vue无缝滚动的插件开发填坑分享相关推荐

  1. [vue] 无缝滚动 vue-seamless-scroll 滚动表格

    npm install vue-seamless-scroll --save main.js import scroll from 'vue-seamless-scroll' Vue.use(scro ...

  2. vue 文字上下循环滚动_基于 Vue 无缝滚动组件Vue-Seamless-Scroll

    今天给小伙伴们推荐一款超棒的Vue无缝滚动组件VueSeamlessScroll. vue-seamless-scroll 基于 vue.js 构建的简单实用的无缝滚动组件.满足丰富的配置需求,支持上 ...

  3. vue工程展示数字动画组件vue animate-number的使用与填坑

    目录 vue工程数字动画组件vue animate-number的使用与填坑 一.基本用法篇 (一).环境配置

  4. Vue无缝滚动轮播插件vue-seamless-scroll

    示例一 示例二 安装  npm install vue-seamless-scroll --save main.js中引入: import scroll from 'vue-seamless-scro ...

  5. 学员使用移动端进行自学的视频动画html,Html5移动端获奖无缝滚动动画实现

    这篇文章主要介绍了Html5移动端获奖无缝滚动动画实现示例,内容挺不错的,现在分享给大家,也给大家做个参考. 本文介绍了Html5移动端获奖无缝滚动动画实现示例,分享给大家,具体如下: 需求分析 哈哈 ...

  6. html无缝滚动原理,Html5移动端获奖无缝滚动动画实现

    这篇文章主要介绍了Html5移动端获奖无缝滚动动画实现示例,内容挺不错的,现在分享给大家,也给大家做个参考. 本文介绍了Html5移动端获奖无缝滚动动画实现示例,分享给大家,具体如下: 需求分析 哈哈 ...

  7. vue列表滚动(无缝衔接)插件分享--超好用

    vue列表滚动(无缝衔接)插件分享–超好用 地址案例演示 1,下载 cnpm i vue-seamless-scroll 2,查看版本号(package.json)文件 3,在要用的组件页面引入 // ...

  8. vue 左右循环滑动_vue实现无缝滚动循环

    大家好,我是一叶,最近做的项目用到循环滚动展示,在这里踩的坑和大家分享一下.一开始写的时候没打算用组件(其实是没找到),思路也很简单.把数据遍历之后,用js获取到可视范围的宽高,再逐次减去他的顶部高度 ...

  9. 基于vue的无缝滚动组件

    vue-seamless-scroll A simple, Seamless scrolling for Vue.js 在awesome上一直没有发现vue的无缝滚动组件,在工作之余写了个组件,分享出 ...

最新文章

  1. javaweb_JSP 的 include 指令的程序
  2. 公司招聘软件研发程序员的一道考题--MS SQL Server数据库数据文件页面头部结构...
  3. webservice / cxf 开发经验总结
  4. JavaScript君,请您坦诚相待~~~
  5. 用c语言实现串的存储结构是指,数据结构学习笔记-串(C语言实现)
  6. 《大道至简》周爱民读后感
  7. SPS中计算值公式函数简介
  8. 2015蓝桥杯C++A:方程整数解;星系炸弹(3种解法)
  9. ServletConfig讲解
  10. GB2312 GBK BIG5
  11. c语言汉字转拼音,c语言汉字转拼音函数源码
  12. 中国当代社会阶层分析——看看你处在社会的哪个阶层?
  13. 使用淘宝api直接上传图片的方法
  14. 【影评】 卧虎藏龙中的人物性格的分析
  15. Canvas 原生实现图片涂抹打马赛克功能
  16. unity 创建自己的像素地图 TileMap
  17. 写给你看的Python Web 岗位分析,求职必备
  18. cms自动更新php文件,织梦cms内容页修改或者删除文章之后自动更新上下篇或者首页...
  19. 【Solr】--简介
  20. C++ CMake入门和进阶(二):CMake语法

热门文章

  1. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性-[Android取经之路]
  2. Field 'id' doesn't have a default value
  3. 最长连续子序列偏移_最长连续不重复子序列
  4. 关于git的使用记录总结
  5. 【数据结构】排序算法总结
  6. hdu 1174:爆头(计算几何,三维叉积求点到线的距离)
  7. 伪共享 FalseSharing (CacheLine,MESI) 浅析以及解决方案
  8. Android TextView中图文混排设置行间距导致高度不一致问题解决
  9. WCF错误远程服务器返回了意外响应: (413) Request Entity Too Large。解决方案
  10. 离线安装python第三方库的实用方法:解决公司内网,服务器/电脑不能上网却需要安装python三方库问题(上:Windows环境中)