Public: 05.12.2015
Download jQuery Slider last version
Slider - an element that lets the user select a value by changing his position on the scale.
Added optional parityPartsAddClass marking even division slider special class partParity.
Added optional partsVisible an array which highlights the values of an array of parts division that marks the class partVisible, and the rest of the class partHide.
/*!
jQuery Slider 1.4.0
https://skidanov.ru/dev/jquery-plugins/slider/
https://github.com/skidanovdima/jquery-slider
*/
;(function($){
$.fn.Slider = function(config, callbacks) {
var container = $(this);
var slider = $('<div></div>');
if (container[0] != undefined) {
if (container.prop('tagName').toUpperCase() == 'INPUT') {
container.hide();
slider = container.wrap(slider).parent();
config.input = container;
} else {
container.replaceWith(slider);
}
var defaultConfig = {
type: 'normal',
// titleWidth need to force the width of each block title adding overflow: hidden.
// Used as a means of combating the asynchronous downloading fonts css, if used in the titles of the slider,
// because they are loaded after document.ready and change the size of the unit after its positioning.
titleWidth: false,
hideCenterTitlesOn768: true,
parityPartsAddClass: true, // Add parity class
partsOn: true,
titlesOn: true,
loadedOn: false,
minPartKey: 0,
maxPartKey: 0,
DefaultValueMin: 0,
DefaultValueMax: 0,
DefaultValue: 0,
runnerCaught: false,
position: 'horizontal',
classes: {
main: 'slider',
skin: 'default',
line: 'line',
parts: 'parts',
back: 'back',
loaded: 'loaded',
complete: 'complete',
minRunner: 'min-runner',
minRunnerImage: 'min-runner-image',
maxRunner: 'max-runner',
maxRunnerImage: 'max-runner-image',
runner: 'runner',
runnerImage: 'runner-image',
titles: 'titles',
part: 'part',
partParity: 'parity',
partVisible: 'part-visible',
partHide: 'part-hide',
partFirst: 'first',
partLast: 'last',
title: 'title',
titleFirst: 'first',
titleLast: 'last',
titleCenter: 'center',
titleHide: 'title-hide',
titleWidth: 'title-width'
}
};
slider.config = $.extend(true, {}, defaultConfig, config);
var defaultCallbacks = {
afterChangeValue: function(slider, user) {
},
events: function(slider) {
}
};
slider.callbacks = $.extend(true, {}, defaultCallbacks, callbacks);
slider.addClass(slider.config.classes.main).addClass(slider.config.classes.skin);
$.fn.Slider.create(slider);
if ( slider.config.type == 'range' ) {
$.fn.Slider.toCount(slider, [slider.config.DefaultValueMin, slider.config.DefaultValueMax], 'range');
} else if ( slider.config.type == 'normal' ) {
$.fn.Slider.toCount(slider, slider.config.DefaultValue, 'normal');
}
$.fn.Slider.events(slider);
return slider;
} else {
return false;
}
};
$.fn.Slider.create = function (slider) {
if ( slider.config.line ) {
slider.config.parts = [];
for (var value = slider.config.line.min; value <= slider.config.line.max; value = value + slider.config.line.step) {
slider.config.parts.push(value);
}
}
slider.components = {}; // Components
slider.components.line = $('<div></div>').addClass(slider.config.classes.line);
if (slider.config.partsOn) {
slider.components.parts = $('<div></div>').addClass(slider.config.classes.parts);
}
slider.components.back = $('<div></div>').addClass(slider.config.classes.back);
if (slider.config.loadedOn) {
slider.components.loaded = $('<div></div>').addClass(slider.config.classes.loaded);
slider.components.back.append(slider.components.loaded);
}
slider.components.complete = $('<div></div>').addClass(slider.config.classes.complete);
if (slider.config.type == 'range') {
slider.components.minRunner = $('<div></div>').addClass(slider.config.classes.minRunner);
slider.components.minRunnerImage = $('<div></div>').addClass(slider.config.classes.minRunnerImage);
slider.components.maxRunner = $('<div></div>').addClass(slider.config.classes.maxRunner);
slider.components.maxRunnerImage = $('<div></div>').addClass(slider.config.classes.maxRunnerImage);
} else {
slider.components.runner = $('<div></div>').addClass(slider.config.classes.runner);
slider.components.runnerImage = $('<div></div>').addClass(slider.config.classes.runnerImage);
}
if (slider.config.titlesOn) {
slider.components.titles = $('<div></div>').addClass(slider.config.classes.titles);
}
if (slider.config.type == 'range') {
slider
.append(slider.components.line
.append(slider.components.parts)
.append(slider.components.back
.append(slider.components.complete)
.append(slider.components.minRunner
.append(slider.components.minRunnerImage)
)
.append(slider.components.maxRunner
.append(slider.components.maxRunnerImage)
)
)
)
.append(slider.components.titles);
} else {
slider
.append(slider.components.line
.append(slider.components.parts)
.append(slider.components.back
.append(slider.components.complete)
.append(slider.components.runner
.append(slider.components.runnerImage)
)
)
)
.append(slider.components.titles);
}
var parity = false;
$.each(slider.config.parts, function (partKey, partValue) {
if (slider.config.partsOn) {
var part = $('<div data-value="'+partValue+'"></div>');
part.addClass(slider.config.classes.part);
if (slider.config.partsVisible) {
if ($.inArray(partValue, slider.config.partsVisible) > -1) {
part.addClass(slider.config.classes.partVisible);
} else {
part.addClass(slider.config.classes.partHide);
}
}
if (slider.config.parityPartsAddClass && parity) {
part.addClass(slider.config.classes.partParity);
}
if (slider.config.position == 'horizontal') {
part.css({left: (partKey) * (100 / (slider.config.parts.length - 1))+'%'});
} else if (slider.config.position == 'vertical') {
part.css({bottom: (partKey) * (100 / (slider.config.parts.length - 1))+'%'});
}
if (partKey == 0) {
// first
part.addClass(slider.config.classes.partFirst);
} else if (partKey == slider.config.parts.length - 1) {
// last
part.addClass(slider.config.classes.partLast);
}
slider.components.parts.append(part);
}
if (slider.config.titlesOn && slider.config.titles && slider.config.titles[partValue]) {
var title = $('<div></div>');
title.append(slider.config.titles[partValue]);
title.addClass(slider.config.classes.title);
if (slider.config.titleWidth) {
title.addClass(slider.config.classes.titleWidth);
title.css({width: slider.config.titleWidth});
}
if (partKey == 0) {
// first
title.addClass(slider.config.classes.titleFirst);
} else if (partKey == slider.config.parts.length - 1) {
// last
title.addClass(slider.config.classes.titleLast);
} else {
// centers
title.addClass(slider.config.classes.titleCenter);
if (slider.config.hideCenterTitlesOn768) {
title.addClass(slider.config.classes.titleHide);
}
if (slider.config.position == 'horizontal') {
title.css({left: (partKey) * (100 / (slider.config.parts.length - 1))+'%'});
} else if (slider.config.position == 'vertical') {
title.css({bottom: (partKey) * (100 / (slider.config.parts.length - 1))+'%'});
}
}
slider.components.titles.append(title);
}
if (parity) {
parity = false;
} else {
parity = true;
}
});
$(document).ready(function(){
$.fn.Slider.titlesCenter(slider);
});
};
$.fn.Slider.titlesCenter = function (slider) {
if (slider.config.titlesOn) {
$.each( slider.components.titles.children('.'+slider.config.classes.title+'.'+slider.config.classes.titleCenter), function (key, val) {
if (slider.config.position == 'horizontal') {
$(this).css({marginLeft: -($(this).outerWidth() / 2)});
} else if (slider.config.position == 'vertical') {
$(this).css({marginBottom: -($(this).outerHeight() / 2)});
}
});
}
};
$.fn.Slider.events = function (slider) {
if($.isTouchCapable()) {
/* jQuery Touch Events https://github.com/benmajor/jQuery-Touch-Events */
slider.components.runner.bind('tapstart', function(event) {
slider.config.runnerCaught = true;
//console.log('Схватили');
$(document).delegate('body', 'touchmove', false);
$('body').bind('tapmove', function(event, touch) {
//console.log('Ведем');
$.fn.Slider.move(slider, event, undefined, touch);
});
});
$(document).bind('tapend', function(event) {
$(document).undelegate('body', 'touchmove', false);
$('body').unbind('tapmove');
});
};
slider.components.line.bind('click', function(event, ui) {
if (slider.config.runnerCaught) {
slider.config.runnerCaught = false;
} else {
//console.log('Кликнули');
$.fn.Slider.move(slider, event, true);
}
});
$(document).bind('mouseup', function(event, ui) {
//console.log('Отпустили');
$('body').css('cursor', 'auto');
$('body').unbind('mousemove');
slider.config.runnerCaught = false;
});
if (slider.config.type == 'range') {
slider.components.minRunner.bind('mousedown', function(event, ui) {
slider.config.runnerCaught = true;
//console.log('Схватили');
$('body').bind('mousemove', function(event, ui) {
//console.log('Ведем');
$('body').css('cursor', 'pointer');
$.fn.Slider.move(slider, event, undefined, undefined, 'min');
});
});
slider.components.maxRunner.bind('mousedown', function(event, ui) {
slider.config.runnerCaught = true;
//console.log('Схватили');
$('body').bind('mousemove', function(event, ui) {
//console.log('Ведем');
$('body').css('cursor', 'pointer');
$.fn.Slider.move(slider, event, undefined, undefined, 'max');
});
});
} else {
slider.components.runner.bind('mousedown', function(event, ui) {
slider.config.runnerCaught = true;
//console.log('Схватили');
$('body').bind('mousemove', function(event, ui) {
//console.log('Ведем');
$('body').css('cursor', 'pointer');
$.fn.Slider.move(slider, event);
});
});
}
slider.callbacks.events(slider);
};
$.fn.Slider.toCount = function (slider, value, type) {
if (type == undefined) type = 'normal';
if ( type == 'range' ) {
slider.valueMin = validator(value[0]);
var v0 = setValue(slider.valueMin);
slider.config.minPartKey = v0;
$.fn.Slider.render(slider, 'min', v0);
slider.valueMax = validator(value[1]);
var v1 = setValue(slider.valueMax);
slider.config.maxPartKey = v1;
$.fn.Slider.render(slider, 'max', v1);
} else if ( type == 'normal' ) {
slider.value = validator(value);
$.fn.Slider.render(slider, 'runner', setValue(slider.value));
} else if (type == 'loaded') {
$.fn.Slider.render(slider, 'loaded', setValue(validator(value)));
//console.log('LOADED' + value);
}
slider.callbacks.afterChangeValue(slider, false);
function validator(value, maxPart) {
if (maxPart == undefined) {maxPart = slider.config.parts[slider.config.parts.length - 1];}
if (value < slider.config.parts[0]) {
value = slider.config.parts[0];
}
if (value > slider.config.parts[slider.config.parts.length - 1]) {
value = slider.config.parts[slider.config.parts.length - 1];
}
return value;
}
function setValue(value){
var returnKey;
$.each(slider.config.parts, function (partKey, partValue) {
if (partKey == 0) {
if (slider.config.parts[partKey + 1]) {
if (value >= partValue && value < partValue + ((slider.config.parts[partKey + 1] - partValue) / 2) ) {
returnKey = partKey;
return false;
}
} else {
// If the first division in the slider only
returnKey = partKey;
return false;
}
} else if (partKey == slider.config.parts.length - 1) {
if (value > partValue - ((partValue - slider.config.parts[partKey - 1]) / 2) && value <= partValue) {
returnKey = partKey;
return false;
}
} else {
if (value > partValue - ((partValue - slider.config.parts[partKey - 1]) / 2) && value <= partValue + ((slider.config.parts[partKey + 1] - partValue) / 2) ) {
returnKey = partKey;
return false;
}
}
});
return returnKey;
}
};
// Отрисовка слайдера (визуальные изменения позиций компонентов)
$.fn.Slider.render = function (slider, type, partKey, animate) {
if (animate) {
if (type == 'max') {
if (slider.config.position == 'horizontal') {
slider.components.complete.css({right: 'auto'});
slider.components.complete.css({left: slider.config.minPartKey * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.stop().animate({width: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'}, 200);
slider.components.maxRunner.stop().animate({left: partKey * 100 / (slider.config.parts.length - 1) + '%'}, 200);
} else if (slider.config.position == 'vertical') {
slider.components.complete.css({top: 'auto'});
slider.components.complete.css({bottom: slider.config.minPartKey * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.stop().animate({height: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'}, 200);
slider.components.maxRunner.stop().animate({bottom: partKey * 100 / (slider.config.parts.length - 1) + '%'}, 200);
}
} else if (type == 'min') {
if (slider.config.position == 'horizontal') {
slider.components.complete.css({left: 'auto'});
slider.components.complete.css({right: ((slider.config.parts.length - 1) - slider.config.maxPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.stop().animate({width: (slider.config.maxPartKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'}, 200);
slider.components.minRunner.stop().animate({left: partKey * 100 / (slider.config.parts.length - 1) +'%'}, 200);
} else if (slider.config.position == 'vertical') {
slider.components.complete.css({bottom: 'auto'});
slider.components.complete.css({top: ((slider.config.parts.length - 1) - slider.config.maxPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.stop().animate({height: (slider.config.maxPartKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'}, 200);
slider.components.minRunner.stop().animate({bottom: partKey * 100 / (slider.config.parts.length - 1) +'%'}, 200);
}
} else if (type == 'runner') {
if (slider.config.position == 'horizontal') {
slider.components.complete.stop().animate({width: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'}, 200);
slider.components.runner.stop().animate({left: partKey * 100 / (slider.config.parts.length - 1) + '%'}, 200);
} else if (slider.config.position == 'vertical') {
slider.components.complete.stop().animate({height: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'}, 200);
slider.components.runner.stop().animate({bottom: partKey * 100 / (slider.config.parts.length - 1) + '%'}, 200);
}
}
} else {
if (type == 'max') {
if (slider.config.position == 'horizontal') {
slider.components.complete.css({right: 'auto'});
slider.components.complete.css({left: slider.config.minPartKey * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.css({width: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.maxRunner.css({left: partKey * 100 / (slider.config.parts.length - 1) + '%'});
} else if (slider.config.position == 'vertical') {
slider.components.complete.css({top: 'auto'});
slider.components.complete.css({bottom: slider.config.minPartKey * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.css({height: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.maxRunner.css({bottom: partKey * 100 / (slider.config.parts.length - 1) + '%'});
}
} else if (type == 'min') {
if (slider.config.position == 'horizontal') {
slider.components.complete.css({left: 'auto'});
slider.components.complete.css({right: ((slider.config.parts.length - 1) - slider.config.maxPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.css({width: (slider.config.maxPartKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.minRunner.css({left: partKey * 100 / (slider.config.parts.length - 1) +'%'});
} else if (slider.config.position == 'vertical') {
slider.components.complete.css({bottom: 'auto'});
slider.components.complete.css({top: ((slider.config.parts.length - 1) - slider.config.maxPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.complete.css({height: (slider.config.maxPartKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.minRunner.css({bottom: partKey * 100 / (slider.config.parts.length - 1) +'%'});
}
} else if (type == 'runner') {
if (slider.config.position == 'horizontal') {
slider.components.complete.css({width: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.runner.css({left: partKey * 100 / (slider.config.parts.length - 1) + '%'});
} else if (slider.config.position == 'vertical') {
slider.components.complete.css({height: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
slider.components.runner.css({bottom: partKey * 100 / (slider.config.parts.length - 1) + '%'});
}
} else if (type == 'loaded') {
slider.components.loaded.css({width: (partKey - slider.config.minPartKey) * 100 / (slider.config.parts.length - 1) + '%'});
}
}
};
$.fn.Slider.move = function (slider, event, animate, touch, runner) {
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
var is_opera = navigator.userAgent.toLowerCase().indexOf("op") > -1;
if (touch) {
var X = touch.position.x + $(window).scrollLeft();
var Y = touch.position.y + $(window).scrollTop();
} else {
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) && is_chrome && !is_opera ) {
var X = event.clientX;
var Y = event.clientY;
} else {
var X = event.clientX + $(window).scrollLeft();
var Y = event.clientY + $(window).scrollTop();
}
}
if (slider.config.position == 'horizontal') {
var clickPosition = X - slider.offset().left;
var partWidth = slider.outerWidth() / (slider.config.parts.length - 1);
} else if (slider.config.position == 'vertical') {
var clickPosition = Y - slider.offset().top;
var partHeight = slider.outerHeight() / (slider.config.parts.length - 1);
}
if (slider.config.position == 'vertical') {
clickPosition = slider.outerHeight() - clickPosition;
}
var valueIsChanged = false;
$.each(slider.config.parts, function (partKey, partValue) {
if (slider.config.position == 'horizontal') {
var begin = ((partKey + 1) * partWidth - partWidth - partWidth / 2);
var end = ((partKey + 1) * partWidth - partWidth + partWidth / 2);
if (end > slider.outerWidth()) {end = slider.outerWidth();}
} else if (slider.config.position == 'vertical') {
var begin = ((partKey + 1) * partHeight - partHeight - partHeight / 2);
var end = ((partKey + 1) * partHeight - partHeight + partHeight / 2);
if (end > slider.outerHeight()) {end = slider.outerHeight();}
}
if (begin < 0) {begin = 0;}
if (clickPosition >= begin && clickPosition < end) {
if (runner == undefined) {
if (slider.config.type == 'normal') {
runner = 'runner';
} else if (slider.config.type == 'range') {
if (partKey <= slider.config.minPartKey) {
runner = 'min';
} else if (partKey >= slider.config.maxPartKey) {
runner = 'max';
} else if (slider.config.maxPartKey - partKey > partKey - slider.config.minPartKey) {
runner = 'min'
} else if (slider.config.maxPartKey - partKey <= partKey - slider.config.minPartKey) {
runner = 'max'
}
}
}
if (runner == 'runner') {
slider.value = partValue;
} else if (runner == 'min') {
slider.valueMin = partValue;
} else if (runner == 'max') {
slider.valueMax = partValue;
}
if (runner == 'min' && partKey >= slider.config.maxPartKey) {
partKey = slider.config.maxPartKey - 1;
slider.valueMin = slider.config.parts[slider.config.maxPartKey - 1];
} else if (runner == 'max' && partKey <= slider.config.minPartKey) {
partKey = slider.config.minPartKey + 1;
slider.valueMax = slider.config.parts[slider.config.minPartKey + 1];
}
if (runner == 'max') {slider.config.maxPartKey = partKey;}
else if (runner == 'min') {slider.config.minPartKey = partKey;}
$.fn.Slider.render(slider, runner, partKey, animate);
valueIsChanged = true;
}
});
if (!valueIsChanged) {
if (clickPosition < 0) {
slider.value = slider.config.parts[0];
} else if (clickPosition > slider.outerWidth()) {
slider.value = slider.config.parts[slider.config.parts.length - 1];
}
}
if (slider.config.input) {
slider.config.input.val(slider.value);
}
slider.callbacks.afterChangeValue(slider, true);
};
}(jQuery));
<script src="http://skidanov.ru/sources/jquery-plugins/jquery.slider/jquery.slider.min.js"></script>
<link rel="stylesheet" href="http://skidanov.ru/sources/jquery-plugins/jquery.slider/css/default.min.css">
<div class="slider default"></div>
;(function($) {
$('.example').Slider({
"parts": [
5000, 10000, 15000, 20000, 25000,
30000, 35000, 40000, 45000, 50000,
55000, 60000, 65000, 70000, 75000,
80000, 85000, 90000, 95000, 100000
],
"partsVisible": [
5000, 25000, 50000, 75000, 100000
],
"titles": {"5000": "5 000", "50000": "50 000", "100000": "100 000"},
"DefaultValue": 30000
}, {
afterChangeValue: function(slider, user) {
// Use variable slider.value to get that value of slider
console.log(slider.value);
},
events: function(slider) {
}
});
}(jQuery));