Улучшаем элемент select

При работе над проектом каждый разработчик стремиться получить одинаковый вид сайта в различных браузерах. К сожалению, большинство основных элементов - стандартные органы управления браузера - почти всегда трудно стилизовать.

В данном уроке мы построим скрипт, который будет преобразовывать обычный элемент select в более стильный и функциональный орган управления.

demosourse

 

HTML

Начнем с разметки HTML. в данном уроке будем использовать разметку HTML5, которая имеет некоторые полезные особенности, такие как атрибуты данных, с помощью которых можно добавлять произвольные данные к разметке на странице.

!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Улучшаем элемент Select с помощью jQuery и CSS3 | Демонстрация для сайта RUSELLER.COM</title>

<link rel="stylesheet" type="text/css" href="css/styles.css" />

</head>
<body>

<div id="page">
	<h1>Ваш продукт</h1>

	<form method="post" action="">
    
    	<!-- Мы собираемся использовать jQuery, чтобы скрыть элемент select и заменить его -->
        
		<select name="fancySelect" class="makeMeFancy">
        
        	<!-- Обратите внимание на атрибуты HTML5 данных -->
        
	        <option value="0" selected="selected" data-skip="1">Выберите продукт</option>
        	<option value="1" data-icon="img/products/js.png" data-html-text="JavaScript + jQuery для начинающих в видеоформате&lt;i&gt;посмотреть видеопрезентацию&lt;/i&gt;">JavaScript + jQuery для начинающих в видеоформате</option>
        	<option value="2" data-icon="img/products/php.png" data-html-text="PHP + MySQL для начинающих&lt;i&gt;купить&lt;/i&gt;">PHP + MySQL для начинающих</option>
            <option value="3" data-icon="img/products/wp.png" data-html-text="WordPress - профессиональный блог за один день&lt;i&gt;скачать&lt;/i&gt;">WordPress - профессиональный блог за один день</option>
            <option value="4" data-icon="img/products/joomla.png" data-html-text="Joomla - профессиональный сайт за один день&lt;i&gt;купить&lt;/i&gt;">Joomla - профессиональный сайт за один день</option>
        </select>
    </form>
    
</div>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="js/script.js"></script>

</body>
</html>

Атрибуты data используются для объединения информации в элементах option. В них размещается иконка продукта и текстовое описание с форматированием. Оба данных пункта будут выводиться в улучшенной версии элемента select.

Произвольный атрибут data-skip в первом элементе сигнализирует нашему скрипту, что данный пункт не надо включать в генерируемый список. Вы можете просто проверить существование атрибутов data-icon и data-html-text и пропустить элемент, если нужно.

Внизу мы включаем библиотеку jQuery версии 1.4.3 (последней версии на момент написания урока) и наш скрипт script.js, который будет разбираться позже.

Улучшенный вариант элемента select

 

jQuery

При обработке события document.ready jQuery проверяет элемент select, и, используя атрибуты данных, строит разметку, которая добавляется сразу за элементом select:

<div style="width: 356px;" class="tzSelect">
	<div class="selectBox expanded">Выберите продукт</div>
	<ul class="dropDown">
		<li><img src="img/products/js.png"><span>JavaScript + jQuery для начинающих в видеоформате<i>посмотреть видеопрезентацию</i></span></li>
		<li><img src="img/products/php.png"><span>PHP + MySQL для начинающих<i>купить</i></span></li>
		<li><img src="img/products/wp.png"><span>WordPress - профессиональный блог за один день<i>скачать</i></span></li>
		<li><img src="img/products/joomla.png"><span>Joomla - профессиональный сайт за один день<i>купить</i></span></li>
	</ul>
</div>

Строится неупорядоченный список с элементами li, которые представляют каждый пункт option из элемента select. А сам элемент select будет представлен элементом div с классом .selectBox.

Теперь можно взглянуть на код JavaScript.

js/script.js

$(document).ready(function(){
	
	// Элемент select, который будет замещаться:
	var select = $('select.makeMeFancy');

	var selectBoxContainer = $('<div>',{
		width		: select.outerWidth(),
		className	: 'tzSelect',
		html		: '<div class="selectBox"></div>'
	});

	var dropDown = $('<ul>',{className:'dropDown'});
	var selectBox = selectBoxContainer.find('.selectBox');
	
	// Цикл по оригинальному элементу select
	
	select.find('option').each(function(i){
		var option = $(this);
		
		if(i==select.attr('selectedIndex')){
			selectBox.html(option.text());
		}
		
		// Так как используется jQuery 1.4.3, то мы можем получить доступ 
		// к атрибутам данных HTML5 с помощью метода data().
		
		if(option.data('skip')){
			return true;
		}
		
		// Создаем выпадающий пункт в соответствии
		// с иконкой данных и атрибутами HTML5 данных:
		
		var li = $('<li>',{
			html:	'<img src="'+option.data('icon')+'" /><span>'+
					option.data('html-text')+'</span>'
		});
				
		li.click(function(){
			
			selectBox.html(option.text());
			dropDown.trigger('hide');
			
			// Когда происходит событие click, мы также отражаем
			// изменения в оригинальном элементе select:
			select.val(option.val());
			
			return false;
		});
		
		dropDown.append(li);
	});
	
	selectBoxContainer.append(dropDown.hide());
	select.hide().after(selectBoxContainer);
	
	// Привязываем пользовательские события show и hide к элементу dropDown:
	
	dropDown.bind('show',function(){
		
		if(dropDown.is(':animated')){
			return false;
		}
		
		selectBox.addClass('expanded');
		dropDown.slideDown();
		
	}).bind('hide',function(){
		
		if(dropDown.is(':animated')){
			return false;
		}
		
		selectBox.removeClass('expanded');
		dropDown.slideUp();
		
	}).bind('toggle',function(){
		if(selectBox.hasClass('expanded')){
			dropDown.trigger('hide');
		}
		else dropDown.trigger('show');
	});
	
	selectBox.click(function(){
		dropDown.trigger('toggle');
		return false;
	});

	// Если нажать кнопку мыши где-нибудь на странице при открытом элементе dropDown,
	// он будет спрятан:
	
	$(document).click(function(){
		dropDown.trigger('hide');
	});
});

После загрузки страницы, скрипт сканирует опции элемента select и генерирует разметку, соответствующую атрибутам данных HTML5, которые содержатся в пунктах элемента select. Так как используется jQuery 1.4.3, то доступ к значениям в данных атрибутах возможен с помощью метода jQuery data(). Это действительно полезная опция, которая существенно облегчает доступ к привязанным данным.

Оригинальный элемент select сохраняется, он будет скрыт с помощью метода hide(). Это важно, потому что все изменения отражаются и в нем. Таким образом, когда вы используете элемент select в форме, значения будут корректно сохранены и переданы вашему скрипту-обработчику.

Теперь наш код на месте и стоит взглянуть на код CSS3.

 

CSS

Мы использовали минимум разметки HTML для вывода элемента выбора и организации выпадающих пунктов. Если ограничивать проект использованием только предшествующих CSS3 технологий, то придется использовать значительно больше элементов div и span.

css/styles.css

#page{
	width:490px;
	margin:50px auto;
}

#page h1{
	font-weight:normal;
	text-indent:-99999px;
	overflow:hidden;
	background:url('../img/your_product.png') no-repeat;
	width:490px;
	height:36px;
}

#page form{
	margin:20px auto;
	width:460px;
}

.tzSelect{
	
	/* Контейнер для нового элемента select */
	
	height:34px;
	display:inline-block;
	min-width:460px;
	position:relative;
	
	/* Предварительная загрузка фонового изображения для выпадающих пунктов */
	background:url("../img/dropdown_slice.png") no-repeat -99999px;
}

.tzSelect .selectBox{
	position:absolute;
	
	height:100%;
	width:100%;
	
	/* Установка шрифта */
	
	font:13px/34px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
	text-align:center;
	text-shadow:1px 1px 0 #EEEEEE;
	color:#666666;

	/* Использование множественных фонов CSS3 */
	
	background:url('../img/select_slice.png') repeat-x #ddd;
	background-image:url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png');
	background-position:0 -136px, right -204px, 50% -68px, 0 0;
	background-repeat: no-repeat, no-repeat, no-repeat, repeat-x;
	
	cursor:pointer;
	
	-moz-border-radius:3px;
	-webkit-border-radius:3px;
	border-radius:3px;
}

.tzSelect .selectBox:hover,
.tzSelect .selectBox.expanded{
	background-position:0 -170px, right -238px, 50% -102px, 0 -34px;
	color:#2c5667;
	text-shadow:1px 1px 0 #9bc2d0;
}

CSS3 позволяет использовать несколько фоновых изображений для одного элемента, просто добавляя дополнительные объявления url() через запятую. Они добавляются к  элементу сверху вниз, то есть, каждое следующее фоновое изображение выводится ниже предыдущего.

Фоновое изображение из частей

В настоящий момент множественные фоновые изображения поддерживаются в Firefox, Safari, Chrome и Opera. Для Internet Explorer и старых версий браузеров, определяется обходной вариант, который просто выводит обычный фон. При разборе документа CSS браузер, который не понимает инструкции для множественных фоновых изображений, просто игнорирует их и использует обычный вариант.

.tzSelect .dropDown{
	position:absolute;
	top:40px;
	left:0;
	width:100%;
	border:1px solid #32333b;
	border-width:0 1px 1px;
	list-style:none;
	
	-moz-box-sizing:border-box;
	-webkit-box-sizing:border-box;
	box-sizing:border-box;
	
	-moz-box-shadow:0 0 4px #111;
	-webkit-box-shadow:0 0 4px #111;
	box-shadow:0 0 4px #111;
}


.tzSelect li{
	height:85px;
	cursor:pointer;
	position:relative;
	
	/* Использование множественных фонов CSS3 */
	
	background:url('../img/dropdown_slice.png') repeat-x #222;
	background-image:url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png');
	background-position: 50% -171px, 0 -85px, 0 0;
	background-repeat: no-repeat, no-repeat, repeat-x;
}

.tzSelect li:hover{
	background-position: 50% -256px, 0 -85px, 0 0;
}

.tzSelect li span{
	left:88px;
	position:absolute;
	top:27px;
}

.tzSelect li i{
	color:#999999;
	display:block;
	font-size:12px;
}

.tzSelect li img{
	left:9px;
	position:absolute;
	top:13px;
}

Свойство box-sizing, которое используется в классе .dropDown, определяет, как рамочка добавляется к общему размеру элемента. Обычно рамочка увеличивает общую ширину элемента на 2px и рушит все выравнивание. Присвоив свойству box-sizing значение border-box, мы предотвращаем увеличение общей ширины, так как рамочка будет размещаться внутри элемента.

Готово!

 

Заключение

В данном уроке продемонстрированы некоторые особенности jQuery 1.4.3 и CSS3. Разработанный скрипт сохраняет оригинальный элемент  select на странице и изменяет его в соответствии с действиями пользователя. Таким образом, форма содержит правильные значения, которые могут быть корректно обработаны другими частями проекта.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: tutorialzine.com/2010/11/better-select-jquery-css3/
Перевел: Сергей Фастунов
Урок создан: 12 Декабря 2010
Просмотров: 85359
Правила перепечатки


5 последних уроков рубрики "Для сайта"

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 12 Декабря 2010 15:16
    businessmilliarder
    Потрясно!
  • 12 Декабря 2010 15:33
    Mazanakisicq
    Я в шоке! Эт просто бомба давно о таком думал но не знал как зделать!!! Спс автору!!!!!
    • 23 Июня 2011 23:44
      askgodtosaveyouu
      сделать через с пишеться грамотеи=)
      • 27 Апреля 2013 02:12
        Virto
        В слове "пишеться" нет мягкого знака, грамотей.
  • 12 Декабря 2010 15:45
    Никита Кратинов
    Классно! Респект автору!
  • 12 Декабря 2010 16:48
    p0staltomsk
    Божественно!
  • 12 Декабря 2010 17:00
    Дмитрий Гунькин
    Бу
  • 12 Декабря 2010 18:22
    budzin
    Спасибо!!!!!! Как раз вовремя :)
  • 12 Декабря 2010 19:51
    Руслан Димитриев
    Нереально, как реально =) Респект автору! Давненько не было таких интересных статей =)
  • 12 Декабря 2010 20:51
    notbot
    ЖЕЕСТЬ! Спасибо, супер!!!!!!!!1111
  • 13 Декабря 2010 00:04
    profesor08
    Наконец-то что-то действительно полезное. Да имеено полезно, что можно использовать на любом сайте. Подправив дизайн под свой сайт.
  • 13 Декабря 2010 11:05
    jackkuk
    У меня криво работает. То ли глюк, то ли архив как-то не так скачивается. Вобщем ерунда на выходе, не все стили работают.
  • 13 Декабря 2010 11:33
    procenko
    Прикол в том, что он не везде работает. IE8 - не пашет нормально.
  • 13 Декабря 2010 16:51
    TavRoX
    прикольно только не вижу селеста там
  • 13 Декабря 2010 17:13
    Антон Буреш
    Хорошая штука, правда я уже давно нашел способ как это сделать =)
  • 15 Декабря 2010 20:19
    sillex
    Не работает, если элементов select больше одного. Как это исправить? Очень нужен.
    • 11 Января 2011 17:47
      Дмитрий Иванов
      Я подправил код, теперь он для нескольких работает. Если всё ещё нужно могу отправить на почту.
      • 23 Февраля 2011 01:04
        choppylion
        как с вами можно связаться? код очень срчоно нужен
      • 11 Апреля 2011 22:07
        sillex
        Здравствуйте, если не сложно отправьте на email. Заранее спасибо.
        • 21 Апреля 2011 14:39
          Дмитрий Иванов
          Тут на сайте уже появился урок где это реализовано.
  • 17 Декабря 2010 17:26
    Даниил Ермошко
    Классно
  • 1 Января 2011 02:04
    Андрей Клековкин
    Евгений.. если не трудно ответить на вопрос.... Я давно наблюдаю за вашими курсами, начиная с ASP А давайте возьменмся за сам дизайн... например Я владею графическими редакторами, могу содрать сайт ну скажем средней сложности.... Но сам создать немогу, нету идеи возможно не идеи.. У меня вкус к дизайну есть, но сам создать немогу. ниче не нравиться... как это называеться и чем лечить.. Я работаю на фриланче верстальщиком, по готовому ТЗ делаю сайты, но себе сайт портфолио так создать и немогу.. мне ничто не нравиться , то что я делаю (говно одно) тоесть с нуля с дизайном, хотя прошел крым и рим и медные трубы.. Смотрю на ваши уроки, откуда все так класно? видимо идей у вас куча.... но подскажите, после чего это победить? У вас курсы на столько понятны, но я хочу научиться именно дизайна сайтов, что мне нужно сделать????? потому как я веб дизайн понял за 1.5-2 года, тоесть графику перенести в веб, и добавить скрипты.... Но я хочу научиться делать хотябы мелкие сайты, с минимальным дизайном но по вкусу.. Я знаю что не рожден с этим... возможно ли научиться дизайну и как и где??????????????????????????????????????????????????????????
    • 17 Января 2011 19:45
      image
      М-да, 1-го января комменты даются с трудом... :)
      • 18 Января 2011 15:11
        Вячеслав Курамшин
        ахахахахаахах +5)))
    • 22 Июля 2011 12:07
      ALEHAN
      Определенно грибочки на новогоднем столе оказались не те) Можно сколько угодно учиться и так и остаться посредственным разработчиком, дизайн - это чувство меры, стиля, вкуса. Если этого нет, то это не привить, этому не выучиться. Проще найти дизайнера.
  • 18 Января 2011 21:49
    a][el
    хорошая вешь но слишком громоздкая штука, редко где нужна бывает, вот обычные селекты http://prootime.ru/select-css
    • 2 Апреля 2012 13:54
      memiko78
      ндя
  • 28 Декабря 2011 23:38
    Spitomen
    Между тем, выбор происходит из списка ТОЛЬКО строки текста, а картинка остается ТОЛЬКО в выпадающем меню. Подскажите как и чего дописать чтобы выбор происходил и картинки и строки из выпадающего меню.
  • 28 Апреля 2013 05:00
    VortK
    Мне понравился, спасибо, но Не происходит моментальная обработка селекта при смене option, но если изменить в др селекте (не переделаном под такой) или инпуте, то он уже посчитает как исправить?
  • 13 Октября 2013 18:56
    Илья427
    Может кто знает как сделать так, чтобы результат выбора отображался не только текстом но и иконкой::??
  • 22 Апреля 2014 19:05
    Yehor
    Подскажите если элементов в списке будет много, как сделать скроллер, как в обычном селект?
  • 23 Октября 2014 16:35
    elizaurus
    Добрый день! Подскажите пожалуйста что не так: Скачал исходники, отредактировал так как мне надо в отдельном файле. все работает. но при переносе в основной файл - перестает работать принципе. Даже не отображается в дефолтом варианте. пробовал и так и сяк. ссылки вначале, ссылки в конце. даже js код вставлял в конец html документа. ничего. JS код полностью оригинальный, не правился. ссылки на картинки проверял несколько раз. Название PNG файлов изменено специально и ссылки исправлены соответственно. HTML-code
    <div class="lang-currency">
    <form method="post" action="#"> <select name="fancySelect" class="makeMeFancy"> <option value="0" selected="selected" data-skip="1">Select Language</option> <option value="1" data-icon="img/ico/gb.png" data-html-text="English">English</option> <option value="2" data-icon="img/ico/ru.png" data-html-text="Русский">Русский</option> <option value="3" data-icon="img/ico/ua.png" data-html-text="Українська">Українська</option> </select>
    </form>
    </div>
    
    CSS-code
    .lang-currency { float: left;
    }
    /* Dropdown jQuery Menu */
    .tzSelect{
    /* Контейнер для нового элемента select */
    height: 25px;
    display: inline-block;
    min-width: 135px;
    position: relative;
    /* Предварительная загрузка фонового изображения для выпадающих пунктов */
    background:url(img/dropdown-slice.png) no-repeat -99999px;
    }
    .tzSelect .selectBox{
    position: absolute;
    height: 100%;
    width: 100%;
    /* Установка шрифта */
    font: 13px/26px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
    text-align: center;
    text-shadow: 1px 1px 0 #EEE;
    color: #666;
    /* Использование множественных фонов CSS3 */
    background:url(img/select-slice.png) repeat-x #ddd;
    background-image:url(img/select-slice.png), url(img/select-slice.png), url(img/select-slice.png), url(img/select-slice.png);
    background-position: 0 -136px, right -204px, 50% -68px, 0 0;
    background-repeat: no-repeat, no-repeat, no-repeat, repeat-x;
    cursor:pointer;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    }
    .tzSelect .selectBox:hover,
    .tzSelect .selectBox.expanded{
    background-position: 0 -170px, right -238px, 50% -102px, 0 -34px;
    color: #2c5667;
    text-shadow: 1px 1px 0 #9bc2d0;
    }
    .tzSelect .dropDown{
    position: absolute;
    top: 25px;
    left: 0;
    width: 100%;
    border: 1px solid #32333b;
    border-width: 0 1px 1px;
    list-style: none;
    -moz-box-sizing: border-box;
    -webkit-box-sizing: order-box;
    box-sizing: border-box;
    -moz-box-shadow: 0 0 4px #111;
    -webkit-box-shadow: 0 0 4px #111;
    box-shadow: 0 0 4px #111;
    }
    .tzSelect li{
    height: 27px;
    cursor: pointer;
    position: relative;
    /* Использование множественных фонов CSS3 */
    background:url(img/dropdown-slice.png) repeat-x #222;
    background-image:url(img/dropdown-slice.png), url(img/dropdown-slice.png), url(img/dropdown-slice.png);
    background-position: 50% -171px, 0 -85px, 0 0;
    background-repeat: no-repeat, no-repeat, repeat-x;
    }
    .tzSelect li:hover{
    background-position: 50% -256px, 0 -85px, 0 0;
    }
    .tzSelect li span{
    left: 50px;
    position: absolute;
    top: 5px;
    }
    .tzSelect li i{
    color: #999;
    display: block;
    font-size: 12px;
    }
    .tzSelect li img{
    left: 20px;
    position: absolute;
    top: 5px;
    }/*Конец Dropdown jQuery menu */
    
  • 27 Ноября 2014 22:36
    msidog
    А можете обновить код до последней версии jquery? а то из-за конфликта версий другие скрипты перестали работать..
^ Наверх ^