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’а, его диапазоном и шагом, иначе изменение значения может быть нелинейным

 

Оцените статью
Добавить комментарий

  1. RomanDrozd

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

  2. mozg

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

  3. hasama

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

  4. Аррис

    В ИЕ работать будет?

  5. KuVa

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

  6. Роман

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

  7. elisei

    firefox — кусок говна

  8. DySprozin

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

  9. программер

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

  10. koeshiro

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

  11. Игорь

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

  12. Олег

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

  13. Сергей

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

  14. melnik.amoti.ru

    не работает выдает ошибку Сведения об ошибке на веб-странице Агент пользователя: 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

  15. Алексей

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

  16. Негаш

    Какого! не работает! без Jquery!!! уныло!

  17. Женя

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

  18. Tarasik

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

  19. Denis

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

  20. Alexey

    Jquery UI slider автору в помощь

  21. Oleg

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