Нестандартные select на jQuery

Подготовил: Евгений Рыжков Дата публикации: 06.04.2009

Задача

Изменить дизайн select. Например на такой:
пример нестандартного select

Требования

  • кроссбраузерность
  • легкость интеграции
  • при отключенном javascript остаются обычные select
  • в длинных списках отбор по первым введенным буквам
  • соответствие HTML и CSS кода стандартам W3C

Материалы

  • selects.png (370b) — составная картинка для всех частей селекта (удобно использовать в качестве примера)
  • selects.css (3.5 Kb) — таблица стилей для нестандартных select
  • selectsComments.css (6.5 Kb) — таблица стилей с комментариями
  • jquery.js (55.9 Kb) — библиотека jQuery версии 1.3.2
  • jsScroll.js (8.13 Kb) — библиотека для реализации нестандартно оформленного скроллинга
  • jquery.selects.js (12 Kb) — библиотека замены select на нестандартные
  • jquery.selects_pack.js (3 Kb) — сжатый скрипт

Алгоритм применения

  1. собираем картинку для оформления select:
    Пример составной картинки для оформления select
    Это составное изображение можно брать за основу для оформления всех частей нестандартного select: левой правой и центральной частей, стрелки и бегунок для прокрутки:
    Пояснения составной картинки для оформления select
    Картинка собрана в одну для оптимизации скорости загрузки страницы — метод спрайтов.
  2. корректируем selects.css для своего проекта: указываем путь к составной картинке, высоту select-а, позиции картинок оформления для частей, цвет и размер шрифта и прочие детали оформления. Свойства, которые можно смело менять в selects.css, снабжены комментариями и помечены как (edit). Изменение остальных свойств может повлечь ошибки в работе и/или отображения select.
  3. создаем классы для указания ширины select-ов:
    .wid100 {
    width: 100px;
    }
    .wid200 {
    width: 200px;
    }
    Имена классов, их количество — произвольны, так же не имеет значения, где эти классы будут описаны. (Лучше классы описывать в selects.css, чтобы все что касается оформления селектов было в одном месте).
  4. указываем созданные классы, name и id для обычных селектов на странице:
    <select class="wid200" id="countries" name="countries">
    <option value="1">Россия</option>
    <option value="2">Украина</option>
    </select>
  5. подключаем таблицу стилей selects.css:
    <link href="css/selects.css" rel="stylesheet" type="text/css" />
  6. подключаем библиотеки: jquery, jsScroll, jquery.selects:
  7. <script src="js/jquery.js" type="text/javascript"></script>
    <script src="js/jquery.selects.js" type="text/javascript"></script>
    <script src="js/jsScroll.js" type="text/javascript"></script>

Демонстрационный пример.

Проверено в:

Скачать демо пример (22 Kb).

Как это работает

При загрузке страницы, если у пользователя включен javascript:

  1. находятся все селекты на странице
  2. заменяется каждый select
    <select id="idSelect" name="nameSelect" class="classSelect">
    <option value="значение option 1">текст option 1</option>
    ...
    <option value="значение option N">текст option N</option>
    </select>
    на конструкцию вида:
    <div class="classSelect">
    <div id="idSelect_fake">
    <span name="значение option 1">текст option 1</span>
    ...
    <span name="значение option N">текст option N</span>
    <input id="idSelect" name="nameSelect" value="value select" />
    </div>
    </div>
  3. обычные select удаляются

Заметки для верстальщика

Проблема Причина Решение
зчем так много !important в selects.css? чтобы сделать конструкцию новых селект по возможности независимой
при внедрении в верстку новые селекты смотрятся криво могут совпадать имена классов/id в selects.css и используемых в верстке изменить имена классов в основных(своих) стлях
при внедрении в верстку новые селекты смотрятся криво может влиять наследование от родителей на div или span, используемые в конструкции select перекрыть наследуемые свойства правилом !important в selects.css
как выстроить два селекта в одну строку? в selects.css для класса selectArea добавляем свойтсво float: left и отступ справа ( margin-right), если нужно
в ie6 возникает ошибка при попытке замены скриптом select ie6 немного странный браузер и временами ведет себя странно. Ошибки могут быть вызваны некорректной восприятием браузера некотрых стилевых свойств нужны эксперементы со свойствами из основных таблиц стилей, которые могут оказывать влияние на конструкцию новых select (это может быть для div свойства float, width, position)

Заметки для программиста

Вопрос Ответ
как получить данные с нового select при отправке данных формой как и с обычного select — по имени (name)
как привязать событие onchange привязываемся к клику по новым option'ам (span). Например:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('#country_fake > span').mousedown(
function()
{
alert("1");
});

});
</script>
обратите внимание на id блока к которому привязываемся — country_fake, country — id селекта, _fake — стандартный префикс. Зная id select'ов, можно привязаться к любому из них
как динамически подгрузить данные в новый select добавляем данные в блок id_selecta_fake. Например:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('#button').click(
function()
{
jQuery('#city_fake').append('<span>Киев</span>'+
'<span>Кривой Рог</span>'+
'<span>Мариуполь</span>"+
'<span>Ужгород</span>');
optionClickHover();
});

});
</script>
optionClickHover() повторная привязка обработчиков событий для вставленных элементов.

Баги

  • 14.12.09 - не работает определение активного пункта по selected="selected" (скоро будет исправлено)

Исправления

  1. теперь работает с версией jquery 1.3.2
  2. не возникают ошибки при наличии скрытых селектов (display: none / visibility: hidden), а также, если они размещены в скрытых блоках
мы верим — тут когда-то будет поиск