`, props: { initialMinValue : { type: Number, default: 0 }, initialMaxValue: { type: Number, default: 5000 }, }, data() { return { min: 0, minValue: 0, maxValue: 5000, max: 5000, step: 10, totalSteps: 0, percentPerStep: 1, trackWidth: null, isDragging: false, pos: {curTrack: null} } }, watch: { initialMinValue(val) { if (val <= this.max && val >= this.min && val < this.maxValue) { this.minValue = parseInt(val); this.revertMoveTrack('track1'); } else if (val < this.min) { this.minValue = this.min; this.revertMoveTrack('track1'); } }, initialMaxValue(val) { if (val <= this.max && val >= this.min && val > this.minValue) { this.maxValue = parseInt(val); this.revertMoveTrack('track2'); } else if (val > this.max) { this.maxValue = this.max; this.revertMoveTrack('track2'); } } }, methods: { revertMoveTrack(track) { if (track === 'track2') { const percent = 100 / this.max * this.maxValue; this.$refs.track2.style.left = percent + '%'; } else if (track === 'track1') { const percent = 100 / this.max * this.minValue; this.$refs.track1.style.left = percent + '%'; } this.setTrackHightlight(); }, moveTrack(track, ev) { let percentInPx = this.getPercentInPx(); let trackX = Math.round(this.$refs._vpcTrack.getBoundingClientRect().left); let clientX = ev.clientX; let moveDiff = clientX - trackX; let moveInPct = moveDiff / percentInPx // if (moveInPct > 100) return; let value = 0; if (moveInPct < 1) { value = 0; } else if (moveInPct > 100) { value = this.max; } else { value = (Math.round(moveInPct / this.percentPerStep) * this.step) + this.min; } if (track === 'track1') { if (value >= (this.maxValue - this.step )) return; this.minValue = value; } if (track === 'track2') { if (value <= (this.minValue + this.step )) return; this.maxValue = value; } if (moveInPct > 0 && moveInPct <= 100) { this.$refs[track].style.left = moveInPct + '%'; this.setTrackHightlight(); } this.$emit('slider-change', {minValue: this.minValue, maxValue: this.maxValue, isDragging: this.isDragging}) }, mousedown(ev, track) { if (this.isDragging) return; this.isDragging = true; this.pos.curTrack = track; }, touchstart(ev, track) { this.mousedown(ev, track) }, mouseup(ev, track) { if (!this.isDragging) return; this.isDragging = false }, touchend(ev, track) { this.mouseup(ev, track) }, mousemove(ev, track) { if (!this.isDragging) return; this.moveTrack(track, ev) }, touchmove(ev, track) { this.mousemove(ev.changedTouches[0], track) }, valueToPercent(value) { return ((value - this.min ) / this.step ) * this.percentPerStep }, setTrackHightlight() { this.$refs.trackHighlight.style.left = this.valueToPercent(this.minValue) + '%' this.$refs.trackHighlight.style.width = (this.valueToPercent(this.maxValue) - this.valueToPercent(this.minValue) ) + '%' }, getPercentInPx() { let trackWidth = this.$refs._vpcTrack.offsetWidth; let oneStepInPx = trackWidth / this.totalSteps; let percentInPx = oneStepInPx / this.percentPerStep; return percentInPx; }, setClickMove(ev) { let track1Left = this.$refs.track1.getBoundingClientRect().left; let track2Left = this.$refs.track2.getBoundingClientRect().left; if (ev.clientX < track1Left) { this.moveTrack('track1', ev) } else if ((ev.clientX - track1Left ) < (track2Left - ev.clientX )) { this.moveTrack('track1', ev) } else { this.moveTrack('track2', ev) } }, onClick(ev) { ev.stopPropagation(); this.setClickMove(ev) }, }, mounted() {// calc per step value this.minValue = this.initialMinValue; this.maxValue = this.initialMaxValue; this.totalSteps = (this.max - this.min ) / this.step; this.percentPerStep = 100 / this.totalSteps; this.$refs.track1.style.left = this.valueToPercent(this.minValue) + '%' this.$refs.track2.style.left = this.valueToPercent(this.maxValue) + '%' this.setTrackHightlight(); var self = this; ['mouseup', 'mousemove'].forEach(type => { document.body.addEventListener(type, (ev) => {// ev.preventDefault(); if (self.isDragging && self.pos.curTrack) { self[type](ev, self.pos.curTrack) } }) }); } });