UNPKG

vue-concise-slider

Version:

vue-slider,A simple sliding component,has easy configuration,support self-adaption / fullscreen / button / page,and is compatible with mobile and PC terminal

218 lines (211 loc) 6.47 kB
export default { props: { options: { type: Object, // 对象或数组且一定会从一个工厂函数返回默认值 default: function () { return {} } } }, name: 'sliderMove', data () { return { data: { poswidth: 0, posheight: 0, start: {}, end: {}, direction: '' }, config: { transitionEnding: false, itemTransitionEnding: false, animation: false, tracking: false, thresholdDistance: this.options.thresholdDistance || 50, thresholdTime: this.options.thresholdTime || 1000, direction: this.options.direction || 'horizontal', freeze: this.options.freeze === undefined ? false : this.options.freeze } } }, methods: { swipeStart (e) { let that = this if (this.config.freeze) { return } if (this.config.transitionEnding) { return } if (this.config.itemTransitionEnding && this.options.itemAnimation) { return } this.config.animation = false // 暂停自动滚动 if (this.options.autoplay) { this.clock().stop(that) } // 阻止页面滚动 if (this.options.preventDocumentMove === true) { document.addEventListener('touchmove', that.preventDefault(e)) } if (e.type === 'touchstart') { if (e.touches.length > 1) { this.config.tracking = false return false } else { this.config.tracking = true /* Hack - would normally use e.timeStamp but it's whack in Fx/Android */ this.data.start.t = new Date().getTime() this.data.start.x = e.targetTouches[0].clientX this.data.start.y = e.targetTouches[0].clientY this.data.end.x = e.targetTouches[0].clientX this.data.end.y = e.targetTouches[0].clientY } } else { this.config.tracking = true /* Hack - would normally use e.timeStamp but it's whack in Fx/Android */ this.data.start.t = new Date().getTime() this.data.start.x = e.clientX this.data.start.y = e.clientY this.data.end.x = e.clientX this.data.end.y = e.clientY } }, swipeMove (e) { if (this.config.tracking) { if (e.type === 'touchmove') { this.data.end.x = e.targetTouches[0].clientX this.data.end.y = e.targetTouches[0].clientY } else { this.data.end.x = e.clientX this.data.end.y = e.clientY } let deltaX = Math.abs(this.data.end.x - this.data.start.x) let deltaY = Math.abs(this.data.end.y - this.data.start.y) if (deltaX >= deltaY && this.config.direction !== 'vertical') { e.preventDefault() } if (deltaX < deltaY && this.config.direction !== 'vertical') { this.config.tracking = false } if (deltaX <= deltaY && this.config.direction === 'vertical') { e.preventDefault() } if (5 * deltaX > deltaY && this.config.direction === 'vertical') { this.config.tracking = false } // 处理嵌套滚动 if (this.config.direction === 'vertical' && deltaX > deltaY) { return false } if (this.config.direction === 'horizontal' && deltaX < deltaY) { return false } return true } return false }, swipeEnd (e) { this.config.tracking = false let now = new Date().getTime() let deltaTime = now - this.data.start.t let currentPage = this.data.currentPage let deltaX = this.data.end.x - this.data.start.x let deltaY = this.data.end.y - this.data.start.y let thresholdDistance = this.config.thresholdDistance // 自动滚动重启 if (this.options.autoplay) { let that = this setTimeout(function () { that.clock().begin(that) }, this.options.autoplay) } // 解除阻止 if (this.options.preventDocumentMove === true) { document.removeEventListener('touchmove', this.preventDefault(e)) } if (deltaTime > this.config.thresholdTime || deltaTime < 100) { this.slide(currentPage) return false } if ( (Math.abs(deltaX) < thresholdDistance || Math.abs(deltaX) < Math.abs(deltaY)) && this.config.direction !== 'vertical' ) { this.slide(currentPage) return false } if ( (Math.abs(deltaY) < thresholdDistance || Math.abs(deltaY) < Math.abs(deltaX)) && this.config.direction === 'vertical' ) { this.slide(currentPage) return false } if (this.config.direction !== 'vertical') { if (deltaX > thresholdDistance) { // swipe right this.pre() return false } else if (-deltaX > thresholdDistance) { // swipe left this.next() return false } else { this.slide(currentPage) return false } } if (this.config.direction === 'vertical') { if (deltaY > thresholdDistance) { // swipe bottom this.pre() return false } else if (-deltaY > thresholdDistance) { // swipe top this.next() return false } else { this.slide(currentPage) return false } } }, swipeOut (e) { if (this.$el === e.target && this.config.tracking) { this.swipeEnd(e) } }, onTransitionEnd (e) { if ( !this.options.loop || (this.data.currentPage > 0 && this.data.currentPage < this.config.sliderLength) ) { return } let that = this setTimeout(function () { let currentPage = that.data.currentPage let sliderLength = that.config.sliderLength that.config.transitionEnding = false if (currentPage < 0) { that.slide(sliderLength + currentPage, 'animationnone') } else if (currentPage >= sliderLength) { that.slide(0 + currentPage - sliderLength, 'animationnone') } }, 0) }, onItemTransitionEnd (e) { if (e.target !== e.currentTarget) { return } var that = this setTimeout(function () { that.config.itemTransitionEnding = false }, 0) } } }