From 2b87ffa91a0340c757f99c286ca42b398dd6a00d Mon Sep 17 00:00:00 2001 From: Sergio Crisostomo Date: Sat, 11 Nov 2017 10:16:43 +0100 Subject: [PATCH] refactor and DRY Slider --- src/components/slider/slider.vue | 415 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 1 file changed, 115 insertions(+), 300 deletions(-) diff --git a/src/components/slider/slider.vue b/src/components/slider/slider.vue index df85723..949a111 100644 --- a/src/components/slider/slider.vue +++ b/src/components/slider/slider.vue @@ -14,34 +14,26 @@
- - +
+ +
+
+
+
+ +
+
+
@@ -109,38 +101,36 @@ } }, data () { + const val = this.checkLimits(Array.isArray(this.value) ? this.value : [this.value]); return { prefixCls: prefixCls, - currentValue: this.value, + currentValue: val, dragging: false, - firstDragging: false, - secondDragging: false, + pointerDown: '', startX: 0, currentX: 0, startPos: 0, newPos: null, - oldSingleValue: this.value, - oldFirstValue: this.value[0], - oldSecondValue: this.value[1], - singlePosition: (this.value - this.min) / (this.max - this.min) * 100, - firstPosition: (this.value[0] - this.min) / (this.max - this.min) * 100, - secondPosition: (this.value[1] - this.min) / (this.max - this.min) * 100 + oldValue: val }; }, watch: { value (val) { - this.currentValue = val; + val = this.checkLimits(Array.isArray(val) ? val : [val]); + if (val[0] !== this.currentValue[0] || val[1] !== this.currentValue[1]) { + this.currentValue = val; + } }, currentValue (val) { this.$nextTick(() => { - this.$refs.tooltip.updatePopper(); + this.$refs.minTooltip.updatePopper(); if (this.range) { - this.$refs.tooltip2.updatePopper(); + this.$refs.maxTooltip.updatePopper(); } }); - this.updateValue(val); - this.$emit('input', val); - this.$emit('on-input', val); + const exportValue = this.range ? val : val[0]; + this.$emit('input', exportValue); + this.$emit('on-input', exportValue); } }, computed: { @@ -154,47 +144,43 @@ } ]; }, - buttonClasses () { + minButtonClasses () { return [ `${prefixCls}-button`, { - [`${prefixCls}-button-dragging`]: this.dragging + [`${prefixCls}-button-dragging`]: this.pointerDown === 'min' } ]; }, - button1Classes () { + maxButtonClasses () { return [ `${prefixCls}-button`, { - [`${prefixCls}-button-dragging`]: this.firstDragging + [`${prefixCls}-button-dragging`]: this.pointerDown === 'max' } ]; }, - button2Classes () { - return [ - `${prefixCls}-button`, - { - [`${prefixCls}-button-dragging`]: this.secondDragging - } - ]; + minPosition () { + const val = this.currentValue; + return (val[0] - this.min) / (this.max - this.min) * 100; + }, + maxPosition: function () { + const val = this.currentValue; + + return (val[1] - this.min) / (this.max - this.min) * 100; }, barStyle () { - let style; + const style = { + left: (this.currentValue[0] - this.min) / (this.max - this.min) * 100 + '%' + }; if (this.range) { - style = { - width: (this.currentValue[1] - this.currentValue[0]) / (this.max - this.min) * 100 + '%', - left: (this.currentValue[0] - this.min) / (this.max - this.min) * 100 + '%' - }; - } else { - style = { - width: (this.currentValue - this.min) / (this.max - this.min) * 100 + '%' - }; + style.width = (this.currentValue[1] - this.currentValue[0]) / (this.max - this.min) * 100 + '%'; } return style; }, - stops() { + stops () { let stopCount = (this.max - this.min) / this.step; let result = []; let stepWidth = 100 * this.step / (this.max - this.min); @@ -211,268 +197,97 @@ } }, methods: { - updateValue (val, init = false) { - if (this.range) { - let value = [...val]; - if (init) { - if (value[0] > value[1]) { - value = [this.min, this.max]; - } - } else { - if (value[0] > value[1]) { - value[0] = value[1]; - } - } - if (value[0] < this.min) { - value[0] = this.min; - } - if (value[0] > this.max) { - value[0] = this.max; - } - if (value[1] < this.min) { - value[1] = this.min; - } - if (value[1] > this.max) { - value[1] = this.max; - } - if (this.value[0] === value[0] && this.value[1] === value[1]) { - this.setFirstPosition(this.currentValue[0]); - this.setSecondPosition(this.currentValue[1]); - return; - } - - this.currentValue = value; - this.setFirstPosition(this.currentValue[0]); - this.setSecondPosition(this.currentValue[1]); - } else { - if (val < this.min) { - this.currentValue = this.min; - } - if (val > this.max) { - this.currentValue = this.max; - } - this.setSinglePosition(this.currentValue); - } + getPointerX (e) { + return e.type.indexOf('touch') !== -1 ? e.touches[0].clientX : e.clientX; }, - sliderClick (event) { - if (this.disabled) return; - const currentX = event.clientX; - const sliderOffsetLeft = this.$refs.slider.getBoundingClientRect().left; - const newPos = (currentX - sliderOffsetLeft) / this.sliderWidth * 100; + checkLimits ([min, max]) { + min = Math.max(0, min); + min = Math.min(100, min); - if (this.range) { - let type = ''; - if (newPos <= this.firstPosition) { - type = 'First'; - } else if (newPos >= this.secondPosition) { - type = 'Second'; - } else { - if ((newPos - this.firstPosition) <= (this.secondPosition - newPos)) { - type = 'First'; - } else { - type = 'Second'; - } - } - this[`change${type}Position`](newPos); - } else { - this.changeSinglePosition(newPos); - } + max = Math.max(0, min, max); + max = Math.min(100, max); + return [min, max]; }, - // for single use - onSingleButtonDown (event) { + onPointerDown (event, type) { if (this.disabled) return; event.preventDefault(); - this.onSingleDragStart(event); -// window.addEventListener('mousemove', this.onSingleDragging); -// window.addEventListener('mouseup', this.onSingleDragEnd); - on(window, 'mousemove', this.onSingleDragging); - on(window, 'mouseup', this.onSingleDragEnd); + this.pointerDown = type; + + this.onPointerDragStart(event); + on(window, 'mousemove', this.onPointerDrag); + on(window, 'touchmove', this.onPointerDrag); + on(window, 'mouseup', this.onPointerDragEnd); + on(window, 'touchend', this.onPointerDragEnd); }, - onSingleDragStart (event) { + onPointerDragStart (event) { this.dragging = false; - this.startX = event.clientX; - this.startPos = parseInt(this.singlePosition, 10); + this.startX = this.getPointerX(event); + this.startPos = parseInt(this[`${this.pointerDown}Position`], 10); }, - onSingleDragging (event) { + onPointerDrag (event) { this.dragging = true; - if (this.dragging) { - this.$refs.tooltip.visible = true; - this.currentX = event.clientX; - const diff = (this.currentX - this.startX) / this.sliderWidth * 100; - this.newPos = this.startPos + diff; - this.changeSinglePosition(this.newPos); - } + this.$refs[`${this.pointerDown}Tooltip`].visible = true; + this.currentX = this.getPointerX(event); + + const diff = (this.currentX - this.startX) / this.sliderWidth * 100; + this.newPos = this.startPos + diff; + this.changeButtonPosition(this.newPos); }, - onSingleDragEnd () { + onPointerDragEnd () { if (this.dragging) { this.dragging = false; - this.$refs.tooltip.visible = false; - this.changeSinglePosition(this.newPos); -// window.removeEventListener('mousemove', this.onSingleDragging); -// window.removeEventListener('mouseup', this.onSingleDragEnd); + this.$refs[`${this.pointerDown}Tooltip`].visible = false; + this.changeButtonPosition(this.newPos); } - off(window, 'mousemove', this.onSingleDragging); - off(window, 'mouseup', this.onSingleDragEnd); + + this.pointerDown = ''; + off(window, 'mousemove', this.onPointerDrag); + off(window, 'touchmove', this.onPointerDrag); + off(window, 'mouseup', this.onPointerDragEnd); + off(window, 'touchend', this.onPointerDragEnd); }, - changeSinglePosition (newPos) { - if (newPos < 0) { - newPos = 0; - } else if (newPos > 100) { - newPos = 100; - } + changeButtonPosition (newPos, forceType) { + + const type = forceType || this.pointerDown; + const index = type === 'min' ? 0 : 1; + if (type === 'min') newPos = this.checkLimits([newPos, this.maxPosition])[0]; + else newPos = this.checkLimits([this.minPosition, newPos])[1]; + const lengthPerStep = 100 / ((this.max - this.min) / this.step); const steps = Math.round(newPos / lengthPerStep); - this.currentValue = Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min); - this.setSinglePosition(this.currentValue); + const value = this.currentValue; + value[index] = Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min); + this.currentValue = [...value]; + if (!this.dragging) { - if (this.currentValue !== this.oldSingleValue) { - this.$emit('on-change', this.currentValue); - this.dispatch('FormItem', 'on-form-change', this.currentValue); - this.oldSingleValue = this.currentValue; + if (this.currentValue[index] !== this.oldValue[index]) { + const exportValue = this.range ? this.currentValue : this.currentValue[0]; + this.$emit('on-change', exportValue); + this.dispatch('FormItem', 'on-form-change', exportValue); + this.oldValue[index] = this.currentValue[index]; } } }, - setSinglePosition (val) { - this.singlePosition = (val - this.min) / (this.max - this.min) * 100; - }, - handleInputChange (val) { - this.currentValue = val; - this.setSinglePosition(val); - this.$emit('on-change', this.currentValue); - this.dispatch('FormItem', 'on-form-change', this.currentValue); - }, - // for range use first - onFirstButtonDown (event) { - if (this.disabled) return; - event.preventDefault(); - this.onFirstDragStart(event); -// window.addEventListener('mousemove', this.onFirstDragging); -// window.addEventListener('mouseup', this.onFirstDragEnd); - on(window, 'mousemove', this.onFirstDragging); - on(window, 'mouseup', this.onFirstDragEnd); - }, - onFirstDragStart (event) { - this.firstDragging = false; - this.startX = event.clientX; - this.startPos = parseInt(this.firstPosition, 10); - }, - onFirstDragging (event) { - this.firstDragging = true; - if (this.firstDragging) { - this.$refs.tooltip.visible = true; - this.currentX = event.clientX; - const diff = (this.currentX - this.startX) / this.sliderWidth * 100; - this.newPos = this.startPos + diff; - this.changeFirstPosition(this.newPos); - } - }, - onFirstDragEnd () { - if (this.firstDragging) { - this.firstDragging = false; - this.$refs.tooltip.visible = false; - this.changeFirstPosition(this.newPos); -// window.removeEventListener('mousemove', this.onFirstDragging); -// window.removeEventListener('mouseup', this.onFirstDragEnd); - } - off(window, 'mousemove', this.onFirstDragging); - off(window, 'mouseup', this.onFirstDragEnd); - }, - changeFirstPosition (newPos) { - if (newPos < 0) { - newPos = 0; - } else if (newPos > this.secondPosition) { - newPos = this.secondPosition; - } - const lengthPerStep = 100 / ((this.max - this.min) / this.step); - const steps = Math.round(newPos / lengthPerStep); - this.currentValue = [Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min), this.currentValue[1]]; - this.setFirstPosition(this.currentValue[0]); - if (!this.firstDragging) { - if (this.currentValue[0] !== this.oldFirstValue) { - this.$emit('on-change', this.currentValue); - this.dispatch('FormItem', 'on-form-change', this.currentValue); - this.oldFirstValue = this.currentValue[0]; - } - } - }, - setFirstPosition (val) { - this.firstPosition = (val - this.min) / (this.max - this.min) * 100; - }, - // for range use second - onSecondButtonDown (event) { + + sliderClick: function (event) { if (this.disabled) return; - event.preventDefault(); - this.onSecondDragStart(event); -// window.addEventListener('mousemove', this.onSecondDragging); -// window.addEventListener('mouseup', this.onSecondDragEnd); - on(window, 'mousemove', this.onSecondDragging); - on(window, 'mouseup', this.onSecondDragEnd); - }, - onSecondDragStart (event) { - this.secondDragging = false; - this.startX = event.clientX; - this.startPos = parseInt(this.secondPosition, 10); - }, - onSecondDragging (event) { - this.secondDragging = true; - if (this.secondDragging) { - this.$refs.tooltip2.visible = true; - this.currentX = event.clientX; - const diff = (this.currentX - this.startX) / this.sliderWidth * 100; - this.newPos = this.startPos + diff; - this.changeSecondPosition(this.newPos); - } - }, - onSecondDragEnd () { - if (this.secondDragging) { - this.secondDragging = false; - this.$refs.tooltip2.visible = false; - this.changeSecondPosition(this.newPos); -// window.removeEventListener('mousemove', this.onSecondDragging); -// window.removeEventListener('mouseup', this.onSecondDragEnd); - } - off(window, 'mousemove', this.onSecondDragging); - off(window, 'mouseup', this.onSecondDragEnd); + const currentX = this.getPointerX(event); + const sliderOffsetLeft = this.$refs.slider.getBoundingClientRect().left; + const newPos = (currentX - sliderOffsetLeft) / this.sliderWidth * 100; + + if (!this.range || newPos <= this.minPosition) this.changeButtonPosition(newPos, 'min'); + else if (newPos >= this.maxPosition) this.changeButtonPosition(newPos, 'max'); + else this.changeButtonPosition(newPos, ((newPos - this.firstPosition) <= (this.secondPosition - newPos)) ? 'min' : 'max'); }, - changeSecondPosition (newPos) { - if (newPos > 100) { - newPos = 100; - } else if (newPos < this.firstPosition) { - newPos = this.firstPosition; - } - const lengthPerStep = 100 / ((this.max - this.min) / this.step); - const steps = Math.round(newPos / lengthPerStep); - this.currentValue = [this.currentValue[0], Math.round(steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min)]; - this.setSecondPosition(this.currentValue[1]); - if (!this.secondDragging) { - if (this.currentValue[1] !== this.oldSecondValue) { - this.$emit('on-change', this.currentValue); - this.dispatch('FormItem', 'on-form-change', this.currentValue); - this.oldSecondValue = this.currentValue[1]; - } - } + handleInputChange (val) { + this.currentValue = [val, this.currentValue[1]]; + const exportValue = this.range ? this.currentValue : this.currentValue[0]; + this.$emit('on-change', exportValue); + this.dispatch('FormItem', 'on-form-change', exportValue); }, - setSecondPosition (val) { - this.secondPosition = (val - this.min) / (this.max - this.min) * 100; - } - }, - mounted () { - if (this.range) { - const isArray = Array.isArray(this.currentValue); - if (!isArray || (isArray && this.currentValue.length != 2) || (isArray && (isNaN(this.currentValue[0]) || isNaN(this.currentValue[1])))) { - this.currentValue = [this.min, this.max]; - } else { - this.updateValue(this.currentValue, true); - } - } else { - if (typeof this.currentValue !== 'number') { - this.currentValue = this.min; - } - this.updateValue(this.currentValue); - } } }; -- libgit2 0.21.4