en.javascript.info/2-ui/5-widgets/5-custom-events/4-slider-events/solution.view/slider.js
2015-02-21 14:58:02 +03:00

88 lines
2.2 KiB
JavaScript

function Slider(options) {
var elem = options.elem;
var thumbElem = elem.querySelector('.thumb');
var max = options.max || 100;
var sliderCoords, thumbCoords, shiftX, shiftY;
// [<*>----------------]
// |...............|
// first last
var pixelsPerValue = (elem.clientWidth - thumbElem.clientWidth) / max;
elem.ondragstart = function() {
return false;
};
elem.onmousedown = function(event) {
if (event.target.closest('.thumb')) {
startDrag(event.clientX, event.clientY);
return false; // disable selection start (cursor change)
}
}
function startDrag(startClientX, startClientY) {
thumbCoords = thumbElem.getBoundingClientRect();
shiftX = startClientX - thumbCoords.left;
shiftY = startClientY - thumbCoords.top;
sliderCoords = elem.getBoundingClientRect();
document.addEventListener('mousemove', onDocumentMouseMove);
document.addEventListener('mouseup', onDocumentMouseUp);
}
function moveTo(clientX) {
// вычесть координату родителя, т.к. position: relative
var newLeft = clientX - shiftX - sliderCoords.left;
// курсор ушёл вне слайдера
if(newLeft < 0) {
newLeft = 0;
}
var rightEdge = elem.offsetWidth - thumbElem.offsetWidth;
if(newLeft > rightEdge) {
newLeft = rightEdge;
}
thumbElem.style.left = newLeft + 'px';
elem.dispatchEvent(new CustomEvent('slide', {
bubbles: true,
detail: positionToValue(newLeft)
}));
}
function valueToPosition(value) {
return pixelsPerValue * value;
}
function positionToValue(left) {
return Math.round( left / pixelsPerValue);
}
function onDocumentMouseMove(e) {
moveTo(e.clientX);
}
function onDocumentMouseUp() {
endDrag();
}
function endDrag() {
document.removeEventListener('mousemove', onDocumentMouseMove);
document.removeEventListener('mouseup', onDocumentMouseUp);
elem.dispatchEvent(new CustomEvent('change', {
bubbles: true,
detail: positionToValue(parseInt(thumbElem.style.left))
}));
}
function setValue(value) {
thumbElem.style.left = valueToPosition(value) + 'px';
}
this.setValue = setValue;
}