Fixed #757 and #775 - Slider Touch support and aria-* issues

pull/827/head
mertsincan 2020-12-23 17:56:48 +03:00
parent 112fe54b40
commit b1ccbb3e72
1 changed files with 60 additions and 88 deletions

View File

@ -1,12 +1,12 @@
<template> <template>
<div :class="containerClass" @click="onBarClick"> <div :class="containerClass" @click="onBarClick">
<span class="p-slider-range" :style="rangeStyle"></span> <span class="p-slider-range" :style="rangeStyle"></span>
<span v-if="!range" class="p-slider-handle" :style="handleStyle" @mousedown="onHandleMouseDown($event)" @keydown="onHandleKeyDown($event)" tabindex="0" <span v-if="!range" class="p-slider-handle" :style="handleStyle" @touchstart="onDragStart($event)" @touchmove="onDrag($event)" @touchend="onDragEnd($event)" @mousedown="onMouseDown($event)" @keydown="onKeyDown($event)" tabindex="0"
role="slider" :aria-valuemin="min" aria-valuenow="modelValue" aria-valuemax="max" :aria-labelledby="ariaLabelledBy"></span> role="slider" :aria-valuemin="min" :aria-valuenow="modelValue" :aria-valuemax="max" :aria-labelledby="ariaLabelledBy"></span>
<span v-if="range" class="p-slider-handle" :style="rangeStartHandleStyle" @mousedown="onHandleMouseDown($event, 0)" @keydown="onHandleKeyDown($event, 0)" tabindex="0" <span v-if="range" class="p-slider-handle" :style="rangeStartHandleStyle" @touchstart="onDragStart($event, 0)" @touchmove="onDrag($event)" @touchend="onDragEnd($event)" @mousedown="onMouseDown($event, 0)" @keydown="onKeyDown($event)" tabindex="0"
role="slider" :aria-valuemin="min" aria-valuenow="modelValue ? modelValue[0] : null" aria-valuemax="max" :aria-labelledby="ariaLabelledBy"></span> role="slider" :aria-valuemin="min" :aria-valuenow="modelValue ? modelValue[0] : null" :aria-valuemax="max" :aria-labelledby="ariaLabelledBy"></span>
<span v-if="range" class="p-slider-handle" :style="rangeEndHandleStyle" @mousedown="onHandleMouseDown($event, 1)" @keydown="onHandleKeyDown($event, 1)" tabindex="0" <span v-if="range" class="p-slider-handle" :style="rangeEndHandleStyle" @touchstart="onDragStart($event, 1)" @touchmove="onDrag($event)" @touchend="onDragEnd($event)" @mousedown="onMouseDown($event, 1)" @keydown="onKeyDown($event, 1)" tabindex="0"
role="slider" :aria-valuemin="min" aria-valuenow="modelValue = modelValue[1] : null" aria-valuemax="max" :aria-labelledby="ariaLabelledBy"></span> role="slider" :aria-valuemin="min" :aria-valuenow="modelValue ? modelValue[1] : null" :aria-valuemax="max" :aria-labelledby="ariaLabelledBy"></span>
</div> </div>
</template> </template>
@ -53,7 +53,7 @@ export default {
barWidth: null, barWidth: null,
barHeight: null, barHeight: null,
dragListener: null, dragListener: null,
mouseupListener: null, dragEndListener: null,
beforeUnmount() { beforeUnmount() {
this.unbindDragListeners(); this.unbindDragListeners();
}, },
@ -65,41 +65,28 @@ export default {
this.barWidth = this.$el.offsetWidth; this.barWidth = this.$el.offsetWidth;
this.barHeight = this.$el.offsetHeight; this.barHeight = this.$el.offsetHeight;
}, },
setValueFromHandlePosition(event, handlePosition) { setValue(event) {
let newValue = (this.max - this.min) * (handlePosition / 100) + this.min; let handleValue;
let pageX = event.touches ? event.touches[0].pageX : event.pageX;
if (this.range) { let pageY = event.touches ? event.touches[0].pageY : event.pageY;
if (this.step) if(this.orientation === 'horizontal')
this.handleStepChange(event, newValue, this.modelValue[this.handleIndex]); handleValue = ((pageX - this.initX) * 100) / (this.barWidth);
else else
this.updateModel(event, newValue); handleValue = (((this.initY + this.barHeight) - pageY) * 100) / (this.barHeight);
let newValue = (this.max - this.min) * (handleValue / 100) + this.min;
if (this.step) {
const oldValue = this.range ? this.modelValue[this.handleIndex] : this.modelValue;
const diff = (newValue - oldValue);
if (diff < 0)
newValue = oldValue + Math.ceil(newValue / this.step - oldValue / this.step) * this.step;
else if (diff > 0)
newValue = oldValue + Math.floor(newValue / this.step - oldValue / this.step) * this.step;
} }
else { this.updateModel(event, newValue);
if (this.step)
this.handleStepChange(event, newValue, this.modelValue);
else
this.updateModel(event, newValue);
}
},
onSlide(event) {
let handlePosition = this.horizontal ? ((event.pageX - this.initX) * 100) / (this.barWidth) : (((this.initY + this.barHeight) - event.pageY) * 100) / (this.barHeight);
this.setValueFromHandlePosition(event, handlePosition);
},
handleStepChange(event, newValue, oldValue) {
let diff = (newValue - oldValue);
let val = oldValue;
if (diff < 0)
val = oldValue + Math.ceil(newValue / this.step - oldValue / this.step) * this.step;
else if (diff > 0)
val = oldValue + Math.floor(newValue / this.step - oldValue / this.step) * this.step;
this.updateModel(event, val);
}, },
updateModel(event, value) { updateModel(event, value) {
let newValue = value; let newValue = value;
let modelValue; let modelValue;
if (this.range) { if (this.range) {
if (this.handleIndex == 0) { if (this.handleIndex == 0) {
if (newValue < this.min) if (newValue < this.min)
@ -113,7 +100,6 @@ export default {
else if (newValue <= this.modelValue[0]) else if (newValue <= this.modelValue[0])
newValue = this.modelValue[0]; newValue = this.modelValue[0];
} }
modelValue = [...this.modelValue]; modelValue = [...this.modelValue];
modelValue[this.handleIndex] = Math.floor(newValue); modelValue[this.handleIndex] = Math.floor(newValue);
} }
@ -122,39 +108,50 @@ export default {
newValue = this.min; newValue = this.min;
else if (newValue > this.max) else if (newValue > this.max)
newValue = this.max; newValue = this.max;
modelValue = Math.floor(newValue); modelValue = Math.floor(newValue);
} }
this.$emit('update:modelValue', modelValue); this.$emit('update:modelValue', modelValue);
this.$emit('change', modelValue); this.$emit('change', modelValue);
}, },
onDragStart(event, index) {
if (this.disabled) {
return;
}
DomHandler.addClass(this.$el, 'p-slider-sliding');
this.dragging = true;
this.updateDomData();
this.handleIndex = index;
event.preventDefault();
},
onDrag(event) {
if (this.dragging) {
this.setValue(event);
event.preventDefault();
}
},
onDragEnd(event) {
if (this.dragging) {
this.dragging = false;
DomHandler.removeClass(this.$el, 'p-slider-sliding');
this.$emit('slideend', {originalEvent: event, value: this.modelValue});
}
},
onBarClick(event) { onBarClick(event) {
if (this.disabled) { if (this.disabled) {
return; return;
} }
if (!DomHandler.hasClass(event.target, 'p-slider-handle')) { if (!DomHandler.hasClass(event.target, 'p-slider-handle')) {
this.updateDomData(); this.updateDomData();
this.onSlide(event); this.setValue(event);
} }
}, },
onHandleMouseDown(event, index) { onMouseDown(event, index) {
if (this.disabled) {
return;
}
DomHandler.addClass(this.$el, 'p-slider-sliding');
this.dragging = true;
this.updateDomData();
this.handleIndex = index;
this.bindDragListeners(); this.bindDragListeners();
event.preventDefault(); this.onDragStart(event, index);
}, },
onHandleKeyDown(event, index) { onKeyDown(event, index) {
this.handleIndex = index; this.handleIndex = index;
switch (event.which) { switch (event.which) {
//down //down
case 40: case 40:
@ -163,7 +160,6 @@ export default {
event.preventDefault(); event.preventDefault();
} }
break; break;
//up //up
case 38: case 38:
if (this.vertical) { if (this.vertical) {
@ -171,7 +167,6 @@ export default {
event.preventDefault(); event.preventDefault();
} }
break; break;
//left //left
case 37: case 37:
if (this.horizontal) { if (this.horizontal) {
@ -179,7 +174,6 @@ export default {
event.preventDefault(); event.preventDefault();
} }
break; break;
//right //right
case 39: case 39:
if (this.horizontal) { if (this.horizontal) {
@ -187,14 +181,12 @@ export default {
event.preventDefault(); event.preventDefault();
} }
break; break;
default: default:
break; break;
} }
}, },
decrementValue(event, index) { decrementValue(event, index) {
let newValue; let newValue;
if (this.range) { if (this.range) {
if (this.step) if (this.step)
newValue = this.modelValue[index] - this.step; newValue = this.modelValue[index] - this.step;
@ -207,14 +199,11 @@ export default {
else else
newValue = this.modelValue - 1; newValue = this.modelValue - 1;
} }
this.updateModel(event, newValue); this.updateModel(event, newValue);
event.preventDefault(); event.preventDefault();
}, },
incrementValue(event, index) { incrementValue(event, index) {
let newValue; let newValue;
if (this.range) { if (this.range) {
if (this.step) if (this.step)
newValue = this.modelValue[index] + this.step; newValue = this.modelValue[index] + this.step;
@ -227,32 +216,17 @@ export default {
else else
newValue = this.modelValue + 1; newValue = this.modelValue + 1;
} }
this.updateModel(event, newValue); this.updateModel(event, newValue);
event.preventDefault(); event.preventDefault();
}, },
bindDragListeners() { bindDragListeners() {
if (!this.dragListener) { if (!this.dragListener) {
this.dragListener = (event) => { this.dragListener = this.onDrag.bind(this);
if (this.dragging) {
this.onSlide(event);
}
};
document.addEventListener('mousemove', this.dragListener); document.addEventListener('mousemove', this.dragListener);
} }
if (!this.dragEndListener) {
if (!this.mouseupListener) { this.dragEndListener = this.onDragEnd.bind(this);
this.mouseupListener = (event) => { document.addEventListener('mouseup', this.dragEndListener);
if (this.dragging) {
this.dragging = false;
DomHandler.removeClass(this.$el, 'p-slider-sliding');
this.$emit('slideend', {originalEvent: event, values: this.modelValue});
}
};
document.addEventListener('mouseup', this.mouseupListener);
} }
}, },
unbindDragListeners() { unbindDragListeners() {
@ -260,10 +234,9 @@ export default {
document.removeEventListener('mousemove', this.dragListener); document.removeEventListener('mousemove', this.dragListener);
this.dragListener = null; this.dragListener = null;
} }
if (this.dragEndListener) {
if (this.mouseupListener) { document.removeEventListener('mouseup', this.dragEndListener);
document.removeEventListener('mouseup', this.mouseupListener); this.dragEndListener = null;
this.mouseupListener = null;
} }
} }
}, },
@ -300,7 +273,6 @@ export default {
return {'left': this.handlePosition + '%'}; return {'left': this.handlePosition + '%'};
else else
return {'bottom': this.handlePosition + '%'}; return {'bottom': this.handlePosition + '%'};
}, },
handlePosition() { handlePosition() {
if (this.modelValue === 0) if (this.modelValue === 0)
@ -380,4 +352,4 @@ export default {
left: 0; left: 0;
width: 100%; width: 100%;
} }
</style> </style>