The original intention of writing plug-ins
1. Seamless rolling effect is often required for projects. MsClass was used as an old plug-in when WRITING JQ, which is relatively easy to use.
2. I turned to Vue. I didn’t find a good seamless scrolling plugin in Vue-Awesome, except for swiper, which was too heavy, so I built my own wheel.
3. In this share, when writing this plug-in pit, also review, if there are flaws in the code welcome to point out.
Source referencevue-seamless-scroll
1. Simple implementation of scrolling up and down base version (original version)
html
1. Solt provides a default slot to place HTML passed in by the parent component
<template>
<div @mouseenter="enter" @mouseleave="leave">
<div ref="wrapper" :style="pos">
<slot></slot>
</div>
</div>
</template>
Copy the code
javascript
1. AnimationFrame API compatibility processing
2. ArrayEqual checks whether the array is equal to listen for changes in data to achieve seamless scrolling of updates
<script> require('comutils/animationFrame') //requestAnimationFrame api const arrayEqual = require('comutils/arrayEqual') export default { data () { return { yPos: 0, reqFrame: null } }, props: { data: {// data Data Type: Array, default: []}, classOption: {// Parameters type: Object, default: {}}}, computed: Transform: 'translate(0,${this.ypos}px)'}}, defaultOption () {return {step: 1, // limitMoveNum: 5, // start seamless scrolling hoverStop: true, // start hover control direction: 1 //1 up 0 down}}, options () {return object.assign ({}, this.defaultoption, this.classoption)}, MoveSwitch () {/ / judgment to the initial value and the length of the data to the rolling to control whether scroll to return this. Data. The length < this. Options. LimitMoveNum}}, the methods: { enter () { if (! this.options.hoverStop || this.moveSwitch) return cancelAnimationFrame(this.reqFrame) }, leave () { if (! this.options.hoverStop || this.moveSwitch) return this._move() }, _move () {/ / scroll enclosing reqFrame = requestAnimationFrame (() = > {let h = this. $refs. Wrapper. OffsetHeight / 2 let direction = this.options.direction if (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') If (this.options. Direction! == 1) { setTimeout(() => { this.yPos = this.$refs.wrapper.offsetHeight / 2 * -1 }, 20) } this._move() } } }, Mounted () {this._initMove()}, watch: {// Select * from db. // Select * from db. arrayEqual(newData, oldData.concat(oldData))) { cancelAnimationFrame(this.reqFrame) this._initMove() } } } } </script>Copy the code
1.1 Optimization 1: Added whether to enable real-time data monitoring refresh on The openWatch
Note the changes to myclass.vue during this commit
1.2 Optimization 2: Added singleHeight waitTime parameter to control whether to scroll in one step
The commit record
1.3 Optimization 3: Added support for mobile touch event scroll lists
The commit record
1.4 Optimization 4: Removed emit callbacks (simplified initialization)
<my-class :data="listData" :class-option="classOption" @copy-data="listData = listData.concat(listData)"<my-class :data= <my-class :data="listData" :class-option="classOption" class="warp">
Copy the code
$emit('copyData') timer = setTimeout(() => {//20ms delay ensures that the innerHtml is retrieved = 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>Copy the code
The commit record
1.5 bug1: Resolve the animationFrame error bug in Internet Explorer 9
The cause of this problem was investigated for a long time. Finally, it was found that the return was not added and the timer ID was not obtained
1.6 Optimization 5: Add left and right seamless scrolling
You can view commit as follows
1.7 Vue.use() provides install global registration
import vueMyCLass from './components/myClass.vue'
let myScroll
const 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
Copy the code
1.8 Bug Solved the single step scrolling failure bug caused by frequent fast operation of touchMove and some code optimization
//1. Encapsulate the unanimate method for multiple calls
_cancle: function _cancle() {
cancelAnimationFrame(this.reqFrame || ' ');
},
Copy the code
//2. Frequent fast operation of touchMove causes scrolling disorder bug
_move() {this._cancle() {this._cancle()}Copy the code
//3. Unanimate before the end of the life cycle
beforeDestroy () {
this._cancle()
}
Copy the code
//4. Fix the bug of not sending parameter warnings
props: {
data: {
type: Array,
default: () => {
return []
}
},
classOption: {
type: Object,
default: () => {
return{}}}}Copy the code
//5.Fixing a bug. add a overflow:hidden on the child element
Margin-top: ‘hidden’; margin-top: ‘hidden’;
computed: {
float () {
return this.options.direction > 1 ? {float: 'left'.overflow: 'hidden'}, {overflow: 'hidden'}
},
pos () {
return {
transform: `translate(The ${this.xPos}px,The ${this.yPos}px)`.transition: `all ease-in The ${this.delay}ms`.overflow: 'hidden'}}}Copy the code
//6. New hover stop function
Previously, this._move() had a built-in delay because of the single step. By default, the single step limited the hover to stop the seamless scrolling. Later, this._move() was implemented with a switch.
commit
TKS
If you’re interested in implementing a similar seamless scroll with native JS, leave a comment, and I can also write seamless Scroll at some point
Vue-seamless – Scroll if you find a bug or something that’s not working, just star it.