[Из песочницы] [Select-Form]: Пишем свой select-список, используя jQuery и CSS

Здравствуйте, хабраюзеры и просто читающие. Сравнительно недавно задался вопросом, как применить стили к тегу select. Всем же хочется, чтобы стилизация формы соответствовала дизайну сайта, а пока что еще не все можно описать чистым CSS. В данной статье мы рассмотрим простенький пример написания своего select-списка, используя CSS и библиотеку языка JavaScript — jQuery. Думаю, особенно новичкам будет любопытен данный материал. Конечно, лучше было бы лучше написать на нативном JS, но всем известно, что строк кода было бы больше, и вряд ли он был бы понятнее.

Честно говоря, прежде чем взяться за создание очередного велосипеда, я пробовал найти подобное решение, но кроме эффектных div-оберток для тега select ничего не нашёл. И я подумал, что будет неплохо написать что-то простенькое и нужное. Ну, что ж, начнём!

В нашем кружке лепки из пластилина участвуют три файла:

  • selectbox.html
  • selectbox.css
  • selectbox.js

Рассмотрим их по очереди. Сначала обратим внимание на самое что ни наесть простое в этом примере — верстка списка или файл selectbox.html:
selectbox.html

    
 

Месяц

  • Январь
  • Февраль
  • Март
  • Апрель
  • Май
  • Июнь
  • Июль
  • Август
  • Сентябрь
  • Октябрь
  • Ноябрь
  • Декабрь


Как видно из исходного html-кода, наш список будет предлагать нам выбрать месяц. Теперь рассмотрим файл selectbox.css:
selectbox.css
div#selectBox {
	width: 250px;
	position: relative;
	height: 50px;
	border-radius: 3px;
	border: solid 1px lightgrey;
	background-color: #fff;
	color: #333;
	cursor: pointer;
	overflow: hidden;
	transition: .3s;
}
div#selectBox p.valueTag {
	padding: 15px;
	cursor: pointer;
	transition: .2s;
	height: 40px;
}

div#selectBox > img.arrow {
	position: absolute;
	right: 0;
	width: 50px;

	padding: 15px;
}

/*
        для пользователей Safari, Chrome и Opera приятный бонус — стилизованный скролл-бар. 
*/
::-webkit-scrollbar {
	background: transparent;
	width: 0.5em;
	position: absolute;
}
::-webkit-scrollbar-track {
	background: transparent;
	position: absolute;
	z-index: -2;
}
::-webkit-scrollbar-thumb {
	border-radius: 100px;
	background: #888;
}

ul#selectMenuBox {
 background: #fff;
 transition: .3s;
 width: 100%;
 height: 200px;
 overflow-y: auto;
 overflow-x: hidden !important;
 position: absolute;
 margin-top: 00px;
 display: block;

}
ul#selectMenuBox > li {
	display: block;
	padding: 10px;
	border-radius: 00px;
	cursor: pointer;
}
ul#selectMenuBox > li.option {
	color: gray;
	padding: 10px;

}
ul#selectMenuBox > li.option:hover {
	color: #333;
	background: #e1e1e1;
	transition: .2s;
}


Особых сложностей тут нет, если вы владеете азами верстки и разметки средствами HTML и CSS3 соответственно.

А теперь к вкусностям! Рассмотрим исходный код плагина selectbox () для jQuery, файл selectbox.js:

selectbox.js
(function( $ ) {
  $.fn.selectbox = function() {
    
    // начальные параметры
    // задаем стандартную высоту div'a. 
    var selectDefaultHeight = $('#selectBox').height();
    // угол поворота изображения в div'e 
    var rotateDefault = "rotate(0deg)";
   
        // после нажатия кнопки срабатывает функция, в которой 
        // вычисляется исходная высота нашего div'a. 
        // очень удобно для сравнения с входящими параметрами (то, что задается в начале скрипта) 
        $('#selectBox > p.valueTag').click(function() {
          // вычисление высоты объекта методом height() 
          var currentHeight = $('#selectBox').height();
          // проверка условия на совпадение/не совпадение с заданной высотой вначале,
          // чтобы понять. что делать дальше. 
          if (currentHeight < 100 || currentHeight == selectDefaultHeight) {
              // если высота блока не менялась и равна высоте, заданной по умолчанию,
              // тогда мы открываем список и выбираем нужный элемент.
              $('#selectBox').height("250px");  // «точка остановки анимации»
              // здесь стилизуем нашу стрелку и делаем анимацию средствами CSS3 
              $('img.arrow').css({borderRadius: "1000px", transition: ".2s", transform: "rotate(180deg)"});
          }


         // иначе если список развернут (высота больше или равна 250 пикселям), 
         // то при нажатии на абзац с классом valueTag, сворачиваем наш список и
         // и присваиваем блоку первоначальную высоту + поворот стрелки в начальное положение
          if (currentHeight >= 250) {
            $('#selectBox').height(selectDefaultHeight);
            $('img.arrow').css({transform: rotateDefault});
          }
      });

     // так же сворачиваем список при выборе нужного элемента 
     // и меняем текст абзаца на текст элемента в списке
      $('li.option').click(function() {
        $('#selectBox').height(selectDefaultHeight);
       $('img.arrow').css({transform: rotateDefault});
        $('p.valueTag').text($(this).text());
      });
  };
})( jQuery );


Кода было больше, но удалось сжать благодаря методам css () и height (). Оформил в виде плагина для удобства и многократного использования. Можно сделать так, как вам нравится, лишь бы работало, так что я не обижусь, если кто-то оптимизирует мой костыль. Для вызова достаточно подключить внешний файл скрипта и вызвать плагин следующим образом:
$('selector').selectbox();

Предварительно, включив вызов в метод ready () объекта document, чтобы плагин загружался после полноценной загрузки документа. Подробнее, что такое плагин на jQuery, можно ознакомиться здесь.

Получилось что-то вроде этого:

image

Спасибо за внимание! Верстайте просто и со стилем!

P.S: Надеюсь, что данная статья кому-то поможет в решении данного/похожего вопроса.

Комментарии (5)

  • 13 октября 2016 в 11:45

    0

    Делать реиспользуемый компонент и обращаться к нему по id — грубейшая ошибка и в стилях и в скриптах.


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


    Отступы в стилях поехали — где один пробел, а где один таб.


    В скрипте неконсистентные кавычки, где одинарные, где двойные — причем в одной строке. Выберите один стиль и соблюдайте его (хинт: большинство выбирает одинарные).

  • 13 октября 2016 в 11:46 (комментарий был изменён)

    0

    В вашем случае получается, что каждый раз нужно описывать кастомный селект довольно сложно, почему бы не сделать тогда уж трансформацию стандартного в то, что вы описываете? И я бы порекомендовал использовать классы, вместо id, чтобы использовать селект несколько раз на странице.
  • 13 октября 2016 в 11:48

    0

    Велосипед, и боль у тех, кто отключил скрипты. Лучше делать стандартные select-ы, и преобразовывать их в кастомные при загрузке.
  • 13 октября 2016 в 11:53

    0

    , а как отображается выпадающее меню когда в низу страницы расположен контрол или когда места не хватает т.к. маленький экран?
  • 13 октября 2016 в 11:57

    0

    Код приведен не полностью, сбросов отступов нет у списка, например.
    Самое нехорошее — то, что этот контрол — не элемент формы, для проброса значений надо использовать скрытое поле (в примере нет). На мобильных работает странно

© Habrahabr.ru