jQuery-плагин для стилизации селектов

Внимание! Дальнейшее развитие и поддержка плагина остановлены в связи с тем, что теперь он является частью другого плагина.

* * *

jQuery-скрипт для стилизации селектов (тег select) html-форм

Одна из самых неприятных (и я бы даже сказал ужасных) вещей в веб-разработке — это верстка html-форм. К сожалению, не существует единого стандарта отображения элементов форм, независимо от браузера и операционной системы, так же, как и нет возможности произвольно оформить некоторые из этих элементов, используя каскадные таблицы стилей.

Не поддаются полной стилизации следующие элементы html-форм:

  • раскрывающийся список <select>;
  • флажок <input type="checkbox">;
  • переключатель <input type="radio">.
  • поле для отправки файла <input type="file">.

Как уже понятно из заголовка поста, здесь речь пойдет только про селекты.

Существует немало готовых решений в виде jQuery-плагинов для стилизации раскрывающихся списков. Но я (ввиду того, что ни один из плагинов меня не устроил по тем или иным причинам) решил пойти путем изобретения своего колеса и написал собственный плагин, которым и делюсь в данной статье.

Сразу хочу заметить, что данный плагин не подходит для всех возможных случаев применения селектов (читайте недостатки).

Демонстрация работы плагина

На отдельной странице вы можете посмотреть пример стилизации селектов с помощью моего плагина. Их оформление я сделал без использования изображений.

Достоинства

  • При отключенном JavaScript отображаются стандартные селекты.
  • Небольшой размер скрипта, примерно 4 килобайта.
  • Работает в IE6+ и всех современных десктопных браузерах.
  • Выводится внутристрочно.
  • Легко поддается оформлению через CSS.
  • Позволяет задать максимальную высоту для выпадающего списка (CSS-свойством max-height).
  • Автоматически подстраивает ширину, если она не указана.
  • Поддерживает прокрутку колесом мыши.
  • Имеет «умное позиционирование», т.е. не уходит за видимую часть страницы при открытии списка.
  • Умеет «ловить» нажатие клавиши Tab и переключаться стрелками на клавиатуре.
  • Поддерживает атрибут «disabled».
  • Работает и с динамически добавляемыми/изменяемыми селектами.

Недостатки

  • Не поддерживает атрибут multiple, т.е. не позволяет выбирать несколько пунктов (мультиселект).
  • Не поддерживает группировку элементов списка (тег <optgroup>).
  • Не поддерживает переключение стрелками на клавиатуре, когда список раскрыт кликом мыши.

Скачать

Плагин недоступен, т.к. он уже не актуален.

jQuery-плагин «SelectBox Styler»

Версия: 1.0.1 | Загрузок: 11103 | Размер: 7 Кб | Последнее обновление: 07.10.2012

Обновления

22.09.2012
Переделал скрипт в плагин (в том числе сделал минимизированный вариант), а также добавил поддержку динамического добавления/изменения селектов.
07.10.2012
Исправлено поведение скрипта при использовании метода onchange у тега <select>.

Подключение плагина

  1. Если на сайте еще не подключен jQuery, то добавьте следующую строку перед тегом </head>:

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
  2. Сразу после jQuery подключите файл со скриптом:

    <script src="ПУТЬ_К_ФАЙЛУ/jquery.selectbox.min.js"></script>
  3. Далее задействуйте плагин:

    <script>
    (function($) {
     $(function() {
    
     $('select').selectbox();
    
    })
    })(jQuery)
    </script>
    

    Этот код поместите перед тегом </head> после вышеуказанных файлов.

  4. При динамическом изменении селектов необходимо запустить триггер refresh, например:

    (function($) {
    $(function() {
    
    	$('button').click(function() {
    		$('select').find('option:nth-child(5)').attr('selected', true);
    		$('select').trigger('refresh');
    	})
    
    })
    })(jQuery)
    

HTML-код после выполнения плагина

Его структура выглядит следующим образом:

<span class="selectbox" style="display: inline-block; position: relative">
	<div class="select" style="float: left; position: relative; z-index: 10000">
		<div class="text">-- Выберите --</div>
		<b class="trigger"><i class="arrow"></i></b>
	</div>
	<div class="dropdown" style="position: absolute; z-index: 9999; overflow-y: auto; overflow-x: hidden; list-style: none; left: 0; display: none">
		<ul>
			<li>-- Выберите --</li>
			<li>Пункт 1</li>
			<li>Пункт 2</li>
			<li>Пункт 3</li>
		</ul>
	</div>
</span>
<select style="position: absolute; top: -9999px">
	<option>-- Выберите --</option>
	<option>Пункт 1</option>
	<option>Пункт 2</option>
	<option>Пункт 3</option>
</select>

CSS-классы, используемые для оформления селекта

Чтобы оформить селекты с помощью CSS, используйте следующие классы:

.selectboxродительский контейнер для всего селекта
.selectbox .selectселект в свернутом состоянии
.selectbox.focused .selectфокус на селекте, когда нажата клавиша Tab
.selectbox .select .textвложенный тег для свернутого селекта на случай вставки фонового изображения по технике «раздвижных дверей»
.selectbox .triggerправая часть свернутого селекта (условный переключатель)
.selectbox .trigger .arrowвложенный тег для переключателя (стрелка)
.selectbox .dropdownобертка для выпадающего списка
.selectbox .dropdown ulвыпадающий список
.selectbox liпункт (опция) селекта
.selectbox li.selectedвыбранный пункт селекта
.selectbox li.disabledотключенный (недоступный для выбора) пункт селекта

Заключение

Создание подобного скрипта — довольно кропотливое занятие, поскольку приходится учитывать множество различных моментов. Очень надеюсь, что никаких серьезных багов не вылезет. Но, если что, сообщайте в комментариях.

В ближайших постах планирую поделиться аналогичными скриптами для <input type="checkbox"> и <input type="radio">.

Комментарии (105)
  1. 1
    alex

    Недостатоток огараничение ширины у выпадающего списка, то есть если select 100px то и выпадающий список тоже 100px, и значение option будет записываться больше одной строке!

  2. 2
    Сергей

    Привет.
    не работает. Он все равно активен.
    Подскажи в чем дело. спасибо.

  3. 3
    Андрей

    у вас проблема со скриптом. Если значение value у option не совпадает с текстом в нём, то что глюк в скрипте?

    <select><option value="0">пыаывавыа</option>
    <option value="1">иепопвапрпа</option></select>
    

    я сделал так.
    При генерации списка ddlist добавил значение option в id li
    А при клике:

    li.filter(':not(.disabled)').click(function() {
     var liText = $(this).text();
     var value = $(this).attr('id');
     if(value != '') {
     el.val(value);
     } else {
     el.val(liText);
     }
     el.change();
     $(divText).val(liText);
     $(this).addClass('selected sel').siblings().removeClass('selected sel');
     $(this).toggleClass('selected');
     dropdown.hide();
     });
    
  4. 5
    Сергей

    Привет.

    <select disabled></select>

    не работает. Селект все равно активен.
    Подскажи в чем дело. спасибо.

  5. 8

    Дальнейшее развитие и поддержка плагина остановлены в связи с тем, что теперь он является частью другого плагина.