JavaScript Slider (ползунок)

Ниже приведен пример реализации такого элемента пользовательского интерфейса как slider или, в простонародии, ползунок с помощью JavaScript.
Задача скрипта такова, чтобы можно было размещать на странице произвольное количество slider’ов и контролировать (получать/задавать) их состояние, а также была возможность изменять внешний вид элементов. Ну и конечно же не забываем про кроссбраузерность.

Сначала подготовим css классы:

.slider {
	background-image: url(hbg.gif);
	background-repeat: repeat-x;
}
.knob {
	position: relative;
	background-image: url(knob.gif);
}

В теле html документа определим блоки для размещения slider’ов:

<div id="sl"></div>
<div id="sl2"></div>

JavaScript класс ползуна:

function slider(elemId, sliderWidth, range1, range2, step) {
	var knobWidth = 17;				// ширина и высота бегунка
	var knobHeight = 21;			// изменяются в зависимости от используемых изображений
	var sliderHeight = 21;			// высота slider'а

	var offsX,tmp;					// вспомагательные переменные
	var d = document;
	var isIE = d.all || window.opera;	// определяем модель DOM
	var point = (sliderWidth-knobWidth-3)/(range2-range1);
	// point - количество пикселей на единицу значения

	var slider = d.createElement('DIV'); // создаем slider
	slider.id = elemId + '_slider';
	slider.className = 'slider';
	d.getElementById(elemId).appendChild(slider);

	var knob = d.createElement('DIV');	// создаем ползунок
	knob.id = elemId + '_knob';
	knob.className = 'knob';
	slider.appendChild(knob); // добавляем его в документ

	knob.style.left = 0;			// бегунок в нулевое значение
	knob.style.width = knobWidth+'px';
	knob.style.height = knobHeight+'px';
	slider.style.width = sliderWidth+'px';
	slider.style.height = sliderHeight+'px';

	var sliderOffset = slider.offsetLeft;			// sliderOffset - абсолютное смещение slider'а
	tmp = slider.offsetParent;		// от левого края в пикселях (в IE не работает)
	while(tmp.tagName != 'BODY') {
		sliderOffset += tmp.offsetLeft;		// тут его и находим
		tmp = tmp.offsetParent;
	}

	if(isIE)						// в зависимости от модели DOM
	{								// назначаем слушателей событий
		knob.onmousedown = startCoord;
		slider.onclick = sliderClick;
		knob.onmouseup = endCoord;
		slider.onmouseup = endCoord;
	}
	else {
		knob.addEventListener("mousedown", startCoord, true);
		slider.addEventListener("click", sliderClick, true);
		knob.addEventListener("mouseup", endCoord, true);
		slider.addEventListener("mouseup", endCoord, true);
	}


// далее подробно не описываю, кто захочет - разберется
//////////////////// функции установки/получения значения //////////////////////////

	function setValue(x)	// установка по пикселям
	{
		if(x < 0) knob.style.left = 0;
		else if(x > sliderWidth-knobWidth-3) knob.style.left = (sliderWidth-3-knobWidth)+'px';
		else {
			if(step == 0) knob.style.left = x+'px';
			else knob.style.left = Math.round(x/(step*point))*step*point+'px';
		}
		d.getElementById('info').value = getValue();	// это вывод значения для примера
	}
	function setValue2(x)	// установка по значению
	{
		if(x < range1 || x > range2) alert('Value is not included into a slider range!');
		else setValue((x-range1)*point);

		d.getElementById('info').value = getValue();
	}

	function getValue()
	{return Math.round(parseInt(knob.style.left)/point)+range1;}

//////////////////////////////// слушатели событий ////////////////////////////////////

	function sliderClick(e) {
		var x;
		if(isIE) {
			if(event.srcElement != slider) return; //IE onclick bug
			x = event.offsetX - Math.round(knobWidth/2);
		}
		else x = e.pageX-sliderOffset-knobWidth/2;
		setValue(x);
	}

	function startCoord(e) {
		if(isIE) {
			offsX = event.clientX - parseInt(knob.style.left);
			slider.onmousemove = mov;
		}
		else {
			slider.addEventListener("mousemove", mov, true);
		}
	}

	function mov(e)	{
		var x;
		if(isIE) x = event.clientX-offsX;
		else x = e.pageX-sliderOffset-knobWidth/2;
		setValue(x);
	}

	function endCoord()	{
		if(isIE) slider.onmousemove = null;
		else slider.removeEventListener("mousemove", mov, true);
	}

	// объявляем функции setValue2 и getValue как методы класса
	this.setValue = setValue2;
	this.getValue = getValue;
} // конец класса

var mysl1 = new slider('sl', 300, 0, 200, 20);
var mysl2 = new slider('sl2', 400, 100, 200, 0);

Параметры класса

  • elemId — id элемент, внутри которого будет размещаться slider
  • sliderWidth — длина slider’а в пикселях
  • range1, range2 — нижняя и верхняя граница значений slider’а соответственно
  • step — шаг изменения значения (0 — шаг 1)

Slider длиной 300px, диапазон значений от 0 до 200, шаг 20:

Slider длиной 400px, диапазон значений от 100 до 200, шаг 0 (1):

зачения:

Устанавливать и получать значения можно так:

mysl1.setValue(80);	  // устанавливаемое значение должно попадать в диапазон slider'а
mysl2.getValue();


проблемы:

  • нужно соблюдать пропорции между длиной slider’а, его диапазоном и шагом, иначе изменение значения может быть нелинейным

21 thoughts on “JavaScript Slider (ползунок)

  1. Спасиб за решение 🙂
    Только вот это пришлось под себя подогнать, чтобы по центру указатель был88 else x = e.pageX-sliderOffset-knobWidth*2-5;
    И в очередной раз убедился, что ИЕ — гавно 🙂 Иногда думаешь, что проще убить всех пользователей ИЕ, чем написать что-то под него..

  2. Большое спасибо! Очень хорошая статья!
    А каким способом можно привить к каждому Slider"у свое значение? Немогли бы вы немного дописать статью в этом смысле? А то я новичок и плохо пока разбераюсь.Заранее большое спасибо!!!

  3. Спасибо за реализацию.
    Замеченые ошибки:
    С параметром css body{margin: 0;} ползунок передвигается рывками.
    Не работает в Opera 9.5-9.6
    В Mozilla Firefox 3.0 перетаскивается картинка бегунка.

  4. Очень дельный сайт! Спасибо автору за умение сказать просто и понятно о сложном. Как пожелание, очень хотелось бы увидеть (и почитать/поизучать) подробную и понятную статью автора об устройстве механизма событий в JS и работы с ними. В различных манускриптах по JS на этот счет больше тумана, чем ясности (захваты/перехваты — кого, кем, для чего???, всплывания, слушания и т.п.)

  5. Почему браузер не отображает слайдер? Подключил скрипт. присвоил стили. сохранил графику. вывел div'ы. Хотелось бы услышать возможные причины. Спасибо!

  6. >В Mozilla Firefox 3.0 перетаскивается картинка бегунка. Нашел как исправить. В начале функции надо вставить: document.ondragstart = test; function test() {return false} Пример работы можно посмотреть на форуме http://forum.anabot.ru (мод "Мое настроение", находится в начале страницы. Если лень регаться, то логин/пароль test2easy/123456)

  7. Возникла проблемка. Если ползунок находиться в блоке со свойством display:none, а потом присвоить display:block, то ползунок не работает, в чём может быть дело?

  8. Мда, прикольно, но не то, спасибо автору, старался человек, а на счёт IE "гавно" не согласен, под него мне лично проще писать. . . .

  9. Как вебмастер могу сказать, пишите изначально под ИЕ (по понятным причинам самое большое количество пользователей), а потом подгоняйте под мозилу, оперу… И сразу поймете, что как раз все остальные браузеры — сплошные глюки,- но они правда пытаются, в конечном этоге, стать ИЕ…

  10. mouseup надо ставить не на слайдер, а на document.body тогда не будет такого бага: начинаем двигать ползунок, отводим мышку с зажатой кнопкой в сторону, отпускаем мышку, а ползунок до сих пор двигается за мышкой.

  11. Прикрутил движок к проекту на микроконтроллере PIC18F97J60. работет и даже все устраивает не смог передавать значение переменных методо GET. у меня почемуто значение любого движка записывается в одно поле с одним именем переменной. Не могли бы объяснить как передавать положение нескольких движков.

  12. не работает выдает ошибку Сведения об ошибке на веб-странице Агент пользователя: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; .NET4.0E) штамп времени: Wed, 20 Feb 2013 14:25:01 UTC Сообщение: 'getElementById(…)' — есть null или не является объектом Строка: 015 Символ: 2 Код: 0 URI-код: file:///E:/Documents%20and%20Settings/Admin/Рабочий%20стол/Slider/shcale.html

  13. Здравствуйте, уважаемый владелец сайта! Мне очень понравился ваш сайт. У вас много полезной и интересной информации. У меня к Вам деловое предложение по еще большей раскрутке Вашего сайта, увеличению притока посетителей на Ваш сайт, созданию бизнеса в Интернете с приличным доходом уже на первоначальном этапе, а также раскрутка любого бизнеса. Это реальный шанс построить за короткое время себе пассивный доход. Для этого просто добавьтесь ко мне с скайп: alekseiwww75 и я дам Вам информацию, а Вы оцените насколько это может Вам помочь.

  14. ЁКЛМН Файлы так трудно что ли прикрепить к статье? 2 за оформление

  15. Люди добрые, а как ползунок вертикально расположить?

  16. Спасибо большое. Очень помогла статья. Прикрутил ваш код к своему и переделал под себя.

  17. UI от JQUERY это из пушки по воробьям. На хрена тащить библиотеку из-за маленького ползунка??? Раньше тоже юзал UI, потом стал писать свои короткие скрипты по мере надобности. Ибо должно быть столько, сколько нужно. Не более. Тем более когда куча интерактива на странице.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *