@zengxiaohui/vue3-seamless-scroll
Version:
一个兼容vue 2.x-3.x 的vue-seamless-scroll区域滚动插件
3 lines (2 loc) • 16.5 kB
JavaScript
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i(require("vue")):"function"==typeof define&&define.amd?define(["vue"],i):(t="undefined"!=typeof globalThis?globalThis:t||self).vue3SeamlessScroll=i(t.vue)}(this,(function(t){"use strict";var i=function(){window.cancelAnimationFrame=window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||window.oCancelAnimationFrame||window.msCancelAnimationFrame||function(t){return window.clearTimeout(t)},window.requestAnimationFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)}},e=function(t,i){if(t===i)return!0;if(t.length!==i.length)return!1;for(var e=0;e<t.length;++e)if(t[e]!==i[e])return!1;return!0};i();const s={name:"vue-seamless-scroll",data:()=>({xPos:0,yPos:0,delay:0,copyHtml:"",height:0,width:0,realBoxWidth:0}),props:{data:{type:Array,default:()=>[]},classOption:{type:Object,default:()=>({})}},computed:{leftSwitchState(){return this.xPos<0},rightSwitchState(){return Math.abs(this.xPos)<this.realBoxWidth-this.width},leftSwitchClass(){return this.leftSwitchState?"":this.options.switchDisabledClass},rightSwitchClass(){return this.rightSwitchState?"":this.options.switchDisabledClass},leftSwitch(){return{position:"absolute",margin:`${this.height/2}px 0 0 -${this.options.switchOffset}px`,transform:"translate(-100%,-50%)"}},rightSwitch(){return{position:"absolute",margin:`${this.height/2}px 0 0 ${this.width+this.options.switchOffset}px`,transform:"translateY(-50%)"}},float(){return this.isHorizontal?{float:"left",overflow:"hidden"}:{overflow:"hidden"}},pos(){return{transform:`translate(${this.xPos}px,${this.yPos}px)`,transition:`all ${this.ease} ${this.delay}ms`,overflow:"hidden"}},defaultOption:()=>({step:1,stop:!1,limitMoveNum:5,hoverStop:!0,direction:1,openTouch:!0,singleHeight:0,singleWidth:0,waitTime:1e3,switchOffset:30,autoPlay:!0,navigation:!1,switchSingleStep:134,switchDelay:400,switchDisabledClass:"disabled",isSingleRemUnit:!1}),options(){return Object.assign({},this.defaultOption,this.classOption)},navigation(){return this.options.navigation},autoPlay(){return!this.navigation&&this.options.autoPlay},scrollSwitch(){return this.data.length>=this.options.limitMoveNum},hoverStopSwitch(){return this.options.hoverStop&&this.autoPlay&&this.scrollSwitch},canTouchScroll(){return this.options.openTouch},isHorizontal(){return this.options.direction>1},baseFontSize(){return this.options.isSingleRemUnit?parseInt(window.getComputedStyle(document.documentElement,null).fontSize):1},realSingleStopWidth(){return this.options.singleWidth*this.baseFontSize},realSingleStopHeight(){return this.options.singleHeight*this.baseFontSize},step(){let t,i=this.options.step;return t=this.isHorizontal?this.realSingleStopWidth:this.realSingleStopHeight,t>0&&t%i>0&&console.error("如果设置了单步滚动,step需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确。~~~~~"),i}},methods:{reset(){this._cancle(),this._initMove()},leftSwitchClick(){this.leftSwitchState&&(Math.abs(this.xPos)<this.options.switchSingleStep?this.xPos=0:this.xPos+=this.options.switchSingleStep)},rightSwitchClick(){this.rightSwitchState&&(this.realBoxWidth-this.width+this.xPos<this.options.switchSingleStep?this.xPos=this.width-this.realBoxWidth:this.xPos-=this.options.switchSingleStep)},_cancle(){cancelAnimationFrame(this.reqFrame||"")},touchStart(t){if(!this.canTouchScroll)return;let i;const e=t.targetTouches[0],{waitTime:s,singleHeight:o,singleWidth:h}=this.options;this.startPos={x:e.pageX,y:e.pageY},this.startPosY=this.yPos,this.startPosX=this.xPos,o&&h?(i&&clearTimeout(i),i=setTimeout((()=>{this._cancle()}),s+20)):this._cancle()},touchMove(t){if(!this.canTouchScroll||t.targetTouches.length>1||t.scale&&1!==t.scale)return;const i=t.targetTouches[0],{direction:e}=this.options;this.endPos={x:i.pageX-this.startPos.x,y:i.pageY-this.startPos.y},event.preventDefault();const s=Math.abs(this.endPos.x)<Math.abs(this.endPos.y)?1:0;1===s&&e<2?this.yPos=this.startPosY+this.endPos.y:0===s&&e>1&&(this.xPos=this.startPosX+this.endPos.x)},touchEnd(){if(!this.canTouchScroll)return;let t;const i=this.options.direction;if(this.delay=50,1===i)this.yPos>0&&(this.yPos=0);else if(0===i){let t=this.realBoxHeight/2*-1;this.yPos<t&&(this.yPos=t)}else if(2===i)this.xPos>0&&(this.xPos=0);else if(3===i){let t=-1*this.realBoxWidth;this.xPos<t&&(this.xPos=t)}t&&clearTimeout(t),t=setTimeout((()=>{this.delay=0,this._move()}),this.delay)},enter(){this.hoverStopSwitch&&this._stopMove()},leave(){this.hoverStopSwitch&&this._startMove()},_move(){this.isHover||this.options.stop||(this._cancle(),this.reqFrame=requestAnimationFrame((()=>{const t=this.realBoxHeight/2,i=this.realBoxWidth/2;let{direction:e,waitTime:s}=this.options,{step:o}=this;1===e?(Math.abs(this.yPos)>=t&&(this.$emit("ScrollEnd"),this.yPos=0),this.yPos-=o):0===e?(this.yPos>=0&&(this.$emit("ScrollEnd"),this.yPos=-1*t),this.yPos+=o):2===e?(Math.abs(this.xPos)>=i&&(this.$emit("ScrollEnd"),this.xPos=0),this.xPos-=o):3===e&&(this.xPos>=0&&(this.$emit("ScrollEnd"),this.xPos=-1*i),this.xPos+=o),this.singleWaitTime&&clearTimeout(this.singleWaitTime),this.realSingleStopHeight?Math.abs(this.yPos)%this.realSingleStopHeight<o?this.singleWaitTime=setTimeout((()=>{this.SingScrollEnd(),this._move()}),s):this._move():this.realSingleStopWidth&&Math.abs(this.xPos)%this.realSingleStopWidth<o?this.singleWaitTime=setTimeout((()=>{this.SingScrollEnd(),this._move()}),s):this._move()})))},_initMove(){this.$nextTick((()=>{const{switchDelay:t,stop:i}=this.options;if(i)return;const{autoPlay:e,isHorizontal:s}=this;if(this._dataWarm(this.data),this.copyHtml="",s){this.height=this.$refs.wrap.offsetHeight,this.width=this.$refs.wrap.offsetWidth;let t=this.$refs.slotList.offsetWidth;e&&(t=2*t+1),this.$refs.realBox.style.width=t+"px",this.realBoxWidth=t}if(!e)return this.ease="linear",void(this.delay=t);this.ease="ease-in",this.delay=0,this.scrollSwitch?(this.copyHtml=this.$refs.slotList.innerHTML,setTimeout((()=>{this.realBoxHeight=this.$refs.realBox.offsetHeight,this._move()}),0)):(this._cancle(),this.yPos=this.xPos=0)}))},_dataWarm(t){t.length>100&&console.warn(`数据达到了${t.length}条有点多哦~,可能会造成部分老旧浏览器卡顿。`)},_startMove(){this.isHover=!1,this._move()},_stopMove(){this.isHover=!0,this.singleWaitTime&&clearTimeout(this.singleWaitTime),this._cancle()},Change(t){let i;i=function t(i){return Object.keys(i.dataset).length>1?i:i.parentElement&&"vue-seamless-scroll"!==i.parentElement.className?t(i.parentElement):void 0}(t.target),i&&this.$emit("onChange",i.dataset)},SingScrollEnd(){let{direction:t}=this.options;1===t||0===t?this.$emit("SingScrollEnd",this.yPos):this.$emit("SingScrollEnd",this.xPos)}},mounted(){this._initMove()},watch:{data(t,i){this._dataWarm(t),e(t,i)||this.reset()},autoPlay(t){t?this.reset():this._stopMove()}},beforeCreate(){this.reqFrame=null,this.singleWaitTime=null,this.isHover=!1,this.ease="ease-in"},beforeDestroy(){this._cancle(),clearTimeout(this.singleWaitTime)}},o={ref:"wrap"},h=["innerHTML"];s.render=function(i,e,s,n,l,a){return t.openBlock(),t.createElementBlock("div",o,[a.navigation?(t.openBlock(),t.createElementBlock("div",{key:0,style:t.normalizeStyle(a.leftSwitch),class:t.normalizeClass(a.leftSwitchClass),onClick:e[0]||(e[0]=(...t)=>a.leftSwitchClick&&a.leftSwitchClick(...t))},[t.renderSlot(i.$slots,"left-switch")],6)):t.createCommentVNode("",!0),a.navigation?(t.openBlock(),t.createElementBlock("div",{key:1,style:t.normalizeStyle(a.rightSwitch),class:t.normalizeClass(a.rightSwitchClass),onClick:e[1]||(e[1]=(...t)=>a.rightSwitchClick&&a.rightSwitchClick(...t))},[t.renderSlot(i.$slots,"right-switch")],6)):t.createCommentVNode("",!0),t.createElementVNode("div",{ref:"realBox",style:t.normalizeStyle(a.pos),onMouseenter:e[4]||(e[4]=(...t)=>a.enter&&a.enter(...t)),onMouseleave:e[5]||(e[5]=(...t)=>a.leave&&a.leave(...t)),onTouchstart:e[6]||(e[6]=(...t)=>a.touchStart&&a.touchStart(...t)),onTouchmove:e[7]||(e[7]=(...t)=>a.touchMove&&a.touchMove(...t)),onTouchend:e[8]||(e[8]=(...t)=>a.touchEnd&&a.touchEnd(...t))},[t.createElementVNode("div",{ref:"slotList",style:t.normalizeStyle(a.float),onClick:e[2]||(e[2]=(...t)=>a.Change&&a.Change(...t)),class:"vue-seamless-scroll"},[t.renderSlot(i.$slots,"default")],4),t.createElementVNode("div",{innerHTML:l.copyHtml,style:t.normalizeStyle(a.float),onClick:e[3]||(e[3]=(...t)=>a.Change&&a.Change(...t))},null,12,h)],36)],512)},i();const n={name:"vue-seamless-scroll",data:()=>({xPos:0,yPos:0,delay:0,copyHtml:"",height:0,width:0,realBoxWidth:0}),props:{data:{type:Array,default:()=>[]},classOption:{type:Object,default:()=>({})}},computed:{leftSwitchState(){return this.xPos<0},rightSwitchState(){return Math.abs(this.xPos)<this.realBoxWidth-this.width},leftSwitchClass(){return this.leftSwitchState?"":this.options.switchDisabledClass},rightSwitchClass(){return this.rightSwitchState?"":this.options.switchDisabledClass},leftSwitch(){return{position:"absolute",margin:`${this.height/2}px 0 0 -${this.options.switchOffset}px`,transform:"translate(-100%,-50%)"}},rightSwitch(){return{position:"absolute",margin:`${this.height/2}px 0 0 ${this.width+this.options.switchOffset}px`,transform:"translateY(-50%)"}},float(){return this.isHorizontal?{float:"left",overflow:"hidden"}:{overflow:"hidden"}},pos(){return{transform:`translate(${this.xPos}px,${this.yPos}px)`,transition:`all ${this.ease} ${this.delay}ms`,overflow:"hidden"}},defaultOption:()=>({stop:!1,step:1,limitMoveNum:5,hoverStop:!0,direction:1,openTouch:!0,singleHeight:0,singleWidth:0,waitTime:1e3,switchOffset:30,autoPlay:!0,navigation:!1,switchSingleStep:134,switchDelay:400,switchDisabledClass:"disabled",isSingleRemUnit:!1}),options(){return Object.assign({},this.defaultOption,this.classOption)},navigation(){return this.options.navigation},autoPlay(){return!this.navigation&&this.options.autoPlay},scrollSwitch(){return this.data.length>=this.options.limitMoveNum},hoverStopSwitch(){return this.options.hoverStop&&this.autoPlay&&this.scrollSwitch},canTouchScroll(){return this.options.openTouch},isHorizontal(){return this.options.direction>1},baseFontSize(){return this.options.isSingleRemUnit?parseInt(window.getComputedStyle(document.documentElement,null).fontSize):1},realSingleStopWidth(){return this.options.singleWidth*this.baseFontSize},realSingleStopHeight(){return this.options.singleHeight*this.baseFontSize},step(){let t,i=this.options.step;return t=this.isHorizontal?this.realSingleStopWidth:this.realSingleStopHeight,t>0&&t%i>0&&console.error("如果设置了单步滚动,step需是单步大小的约数,否则无法保证单步滚动结束的位置是否准确。~~~~~"),i}},methods:{reset(){this._cancle(),this._initMove()},leftSwitchClick(){this.leftSwitchState&&(Math.abs(this.xPos)<this.options.switchSingleStep?this.xPos=0:this.xPos+=this.options.switchSingleStep)},rightSwitchClick(){this.rightSwitchState&&(this.realBoxWidth-this.width+this.xPos<this.options.switchSingleStep?this.xPos=this.width-this.realBoxWidth:this.xPos-=this.options.switchSingleStep)},_cancle(){cancelAnimationFrame(this.reqFrame||"")},touchStart(t){if(!this.canTouchScroll)return;let i;const e=t.targetTouches[0],{waitTime:s,singleHeight:o,singleWidth:h}=this.options;this.startPos={x:e.pageX,y:e.pageY},this.startPosY=this.yPos,this.startPosX=this.xPos,o&&h?(i&&clearTimeout(i),i=setTimeout((()=>{this._cancle()}),s+20)):this._cancle()},touchMove(t){if(!this.canTouchScroll||t.targetTouches.length>1||t.scale&&1!==t.scale)return;const i=t.targetTouches[0],{direction:e}=this.options;this.endPos={x:i.pageX-this.startPos.x,y:i.pageY-this.startPos.y},event.preventDefault();const s=Math.abs(this.endPos.x)<Math.abs(this.endPos.y)?1:0;1===s&&e<2?this.yPos=this.startPosY+this.endPos.y:0===s&&e>1&&(this.xPos=this.startPosX+this.endPos.x)},touchEnd(){if(!this.canTouchScroll)return;let t;const i=this.options.direction;if(this.delay=50,1===i)this.yPos>0&&(this.yPos=0);else if(0===i){let t=this.realBoxHeight/2*-1;this.yPos<t&&(this.yPos=t)}else if(2===i)this.xPos>0&&(this.xPos=0);else if(3===i){let t=-1*this.realBoxWidth;this.xPos<t&&(this.xPos=t)}t&&clearTimeout(t),t=setTimeout((()=>{this.delay=0,this._move()}),this.delay)},enter(){this.hoverStopSwitch&&this._stopMove()},leave(){this.hoverStopSwitch&&this._startMove()},_move(){this.isHover||this.options.stop||(this._cancle(),this.reqFrame=requestAnimationFrame(function(){const t=this.realBoxHeight/2,i=this.realBoxWidth/2;let{direction:e,waitTime:s}=this.options,{step:o}=this;1===e?(Math.abs(this.yPos)>=t&&(this.$emit("ScrollEnd"),this.yPos=0),this.yPos-=o):0===e?(this.yPos>=0&&(this.$emit("ScrollEnd"),this.yPos=-1*t),this.yPos+=o):2===e?(Math.abs(this.xPos)>=i&&(this.$emit("ScrollEnd"),this.xPos=0),this.xPos-=o):3===e&&(this.xPos>=0&&(this.$emit("ScrollEnd"),this.xPos=-1*i),this.xPos+=o),this.singleWaitTime&&clearTimeout(this.singleWaitTime),this.realSingleStopHeight?Math.abs(this.yPos)%this.realSingleStopHeight<o?this.singleWaitTime=setTimeout((()=>{this.SingScrollEnd(),this._move()}),s):this._move():this.realSingleStopWidth&&Math.abs(this.xPos)%this.realSingleStopWidth<o?this.singleWaitTime=setTimeout((()=>{this.SingScrollEnd(),this._move()}),s):this._move()}.bind(this)))},_initMove(){this.$nextTick((()=>{const{switchDelay:t,stop:i}=this.options;if(i)return;const{autoPlay:e,isHorizontal:s}=this;if(this._dataWarm(this.data),this.copyHtml="",s){this.height=this.$refs.wrap.offsetHeight,this.width=this.$refs.wrap.offsetWidth;let t=this.$refs.slotList.offsetWidth;e&&(t=2*t+1),this.$refs.realBox.style.width=t+"px",this.realBoxWidth=t}if(!e)return this.ease="linear",void(this.delay=t);this.ease="ease-in",this.delay=0,this.scrollSwitch?(this.copyHtml=this.$refs.slotList.innerHTML,setTimeout((()=>{this.realBoxHeight=this.$refs.realBox.offsetHeight,this._move()}),0)):(this._cancle(),this.yPos=this.xPos=0)}))},_dataWarm(t){t.length>100&&console.warn(`数据达到了${t.length}条有点多哦~,可能会造成部分老旧浏览器卡顿。`)},_startMove(){this.isHover=!1,this._move()},_stopMove(){this.isHover=!0,this.singleWaitTime&&clearTimeout(this.singleWaitTime),this._cancle()},Change(t){let i;i=function t(i){return Object.keys(i.dataset).length>1?i:i.parentElement&&"vue-seamless-scroll"!==i.parentElement.className?t(i.parentElement):void 0}(t.target),i&&this.$emit("onChange",i.dataset)},SingScrollEnd(){let{direction:t}=this.options;1===t||0===t?this.$emit("SingScrollEnd",this.yPos):this.$emit("SingScrollEnd",this.xPos)}},mounted(){this._initMove()},watch:{data(t,i){this._dataWarm(t),e(t,i)||this.reset()},autoPlay(t){t?this.reset():this._stopMove()}},beforeCreate(){this.reqFrame=null,this.singleWaitTime=null,this.isHover=!1,this.ease="ease-in"},beforeDestroy(){this._cancle(),clearTimeout(this.singleWaitTime)}},l={ref:"wrap"},a=["innerHTML"];return n.render=function(i,e,s,o,h,n){return t.openBlock(),t.createElementBlock("div",l,[n.navigation?(t.openBlock(),t.createElementBlock("div",{key:0,style:t.normalizeStyle(n.leftSwitch),class:t.normalizeClass(n.leftSwitchClass),onClick:e[0]||(e[0]=(...t)=>n.leftSwitchClick&&n.leftSwitchClick(...t))},[t.renderSlot(i.$slots,"left-switch")],6)):t.createCommentVNode("",!0),n.navigation?(t.openBlock(),t.createElementBlock("div",{key:1,style:t.normalizeStyle(n.rightSwitch),class:t.normalizeClass(n.rightSwitchClass),onClick:e[1]||(e[1]=(...t)=>n.rightSwitchClick&&n.rightSwitchClick(...t))},[t.renderSlot(i.$slots,"right-switch")],6)):t.createCommentVNode("",!0),t.createElementVNode("div",{ref:"realBox",style:t.normalizeStyle(n.pos),onMouseenter:e[3]||(e[3]=(...t)=>n.enter&&n.enter(...t)),onMouseleave:e[4]||(e[4]=(...t)=>n.leave&&n.leave(...t)),onTouchstart:e[5]||(e[5]=(...t)=>n.touchStart&&n.touchStart(...t)),onTouchmove:e[6]||(e[6]=(...t)=>n.touchMove&&n.touchMove(...t)),onTouchend:e[7]||(e[7]=(...t)=>n.touchEnd&&n.touchEnd(...t))},[t.createElementVNode("div",{ref:"slotList",style:t.normalizeStyle(n.float),onClick:e[2]||(e[2]=(...t)=>n.Change&&n.Change(...t)),class:"vue-seamless-scroll"},[t.renderSlot(i.$slots,"default")],4),t.createElementVNode("div",{innerHTML:h.copyHtml,style:t.normalizeStyle(n.float)},null,12,a)],36)],512)},{install:t=>{parseFloat(t.version)>3?t.component(s.name,s):t.component(n.name,n)}}}));
//# sourceMappingURL=vue3SeamlessScroll-umd.js.map