Вордпресс плагин для стилизации select. IkSelect — идеальный плагин для стилизации селектов. Чем же он лучше остальных

Вордпресс плагин для стилизации select. IkSelect — идеальный плагин для стилизации селектов. Чем же он лучше остальных

Около года назад, я уже делал подробный обзор jQuery-плагинов для стилизации селектов . Итог остался неутешительным, у каждого из них были свои недостатки, и я так и не смог найти то, что хотел. В комментариях отписалось довольно много разработчиков, но все мы сошлись на том, что идеального плагина нет, и что над любым из них приходится хорошо поработать напильником.

Недавно на хабре проскакивал Selectik - довольно неплохой плагин, но не без недостатков . Работа над ним, судя по GitHub , ещё идёт, но пока он не очень удобен, и его основные проблемы ещё имеют место быть.

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

В двух словах: он умеет практически всё, что умеет стандартный селект, при этом отлично стилизируется и подстраивается под особенности реализации селектов разных браузеров. Плагин полностью копирует внешний вид родного селекта Mac OS X, но его без проблем можно стилизировать через css.

Вот так он выглядит в закрытом виде:

Вот так в открытом:

Чем же он лучше остальных?

Объем: 11KB

Достоинства:

  • работает во всех браузерах (IE6+, FF, Opera, Chrome, Safari), в том числе в мобильных
  • автоматически подстраивает ширину
  • открывается всегда на видимую часть страницы (так называемое «умное позиционирование»), как в горизонтальном, так и в вертикальном положении
  • позволяет задавать максимальную высоту выпадающего списка
  • позволяет группировать опции (optgroup)
  • полностью управляется с клавиатуры (в т.ч. реагирует на переход Tab"ом, PgUp, PgDown, Home, End)
  • имеет подбор по первым буквам (не только по одной, но и по последующим)
  • поддерживает скролл колёсиком мышки
  • вставляется инлайново (inline-block)
  • замечательно работает с огромными списками (1000+ элементов)
  • оставляет стандартный селект при отключенном javascript
  • имеет отличный API
Недостатки:
  • не позволяет выделять сразу несколько пунктов (multiselect)
  • не стилизирует скроллбар выпадающего списка (т.к. слишком сильно влияет на скорость работы)
  • не бегает за пивом

Мобильные браузеры

Плагин стилизирует само поле, но при нажатии вызывает родное поведение браузера. Протестировано на iOS (Safari) и Android (2.3 native, Firefox):

В Opera mini остаются стандартные селекты, во избежание перезагрузки страницы при открытии списка. В Opera mobile работает так же, как и в настольной версии.

Кто серьёзно занимается вёрсткой страниц, знает, что возможности стилизации select в CSS крайне сильно ограничены. Но очень часто в дизайн стандартный select не вписывается вообще никак, поэтому приходится делать стилизацию select через JavaScript . Фактически, в этой статье мы с Вами создадим свой собственный select с помощью JavaScript .

Есть масса готовых плагинов, в том числе и на jQuery , которые позволяют всё это сделать. Но если Вам не нужно что-то сверхсложное, то проще сделать всё самому с нуля на чистом JavaScript .

Первым делом, давайте создадим HTML-структуру нашего будущего select :




Элемент 1


Элемент 2


Элемент 3




Как видите, тега select тут и близко нет. Теперь мы можем как угодно стилизовать наш собственный select с помощью CSS :

Select {
background-color: #0ee;
border-radius: 10px;
padding: 10px 0;
width: 200px;
}
.select p {
cursor: pointer;
margin: 0;
padding: 5px 20px;
}
.select p.active {
background-color: #ee0;
}

Безусловно, Вы здесь можете сделать всё, что пожелаете. И, наконец, надо превратить внешний вид в функциональность select , то есть выбор и подстветка только одного элемента из нескольких, а также последующая отправка вместе с формой. Для этого мы воспользуемся JavaScript :

Function select(element) {
var value = element.getAttribute("data-value"); // Считываем значение выбранного элемента
var nodes = element.parentNode.childNodes; // Получаем все остальные элементы
for (var i = 0; i < nodes.length; i++) {
/* Отфильтровываем посторонние элементы text и input */
if (nodes[i] instanceof HTMLParagraphElement) {
/* Добавляем active у выбранного элемента, стирая данный класс у всех остальных */
if (value == nodes[i].getAttribute("data-value")) nodes[i].className = "active";
else nodes[i].className = "";
}
}
document.getElementById("my_select").value = value; // Устанавливаем в hidden-поле выбранное значение
}

Ключевым моментом реализации функциональности select является hidden-поле , в которое записывается значение из нашего select . И именно это значение будет отправлено при отправке формы.

Вот таким нехитрым образом делается абсолютно любая стилизация select на JavaScript . Если использовать jQuery , то код будет ещё проще.

Безусловно, стандартный select обладает большей функциональностью. Например, он реагирует на tab , также можно в нём перебирать элементы стрелками на клавиатуре. Но всё это Вы так же можете реализовать при необходимости на JavaScript .

И последняя рекомендация. В коде был использован тег noscript , и это было неслучайно. Поскольку не у всех JavaScript включён, и чтобы форма была вообще рабочей для таких пользователей, нужно вывести хотя бы стандартный select . А все, у кого JavaScript включён, увидят наш красивый select .

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

Одним из важнейших способов эффективной организации jQuery кода служит превращение его частей в плагины. Такие превращения несут в себя ряд преимуществ: код становится проще модифицировать и сопровождать, руководство повторяющими задачами упрощается. Также увеличивается скорость разработки, так как организация плагина способствует повторному использованию кода.

Поэтому мы и продемонстрируем сегодня процесс конвертирования кода в плагин. Код мы возьмем из этого руководства jQuery& CSS3 замещаем элемент select и превратим его в готовый к использованию jQuery плагин.

Основная идея

Написать jQuery плагин совсем не сложно. Для этого нужно расширить объект $.fn своей собственной функцией. Гораздо сложнее должным образом структурировать свой код, чтобы плагин можно было легко вставить и использовать (без зависимостей).

Вот, несколько проблем, которые нам надо решить при конвертировании кода руководства в jQuery плагин:


1. Пользователю нужно дать возможность решать, какая разметка будет генерироваться для dropdown (выпадающего списка). К примеру, код руководства сильно зависит от наличия data- атрибутов, которые содержат разметку HTML. Это слишком специфично, чтобы подключать в плагин, поэтому данную реализацию нужно исключить.

2. Из-за способа вызова плагина код нужно переписать, чтобы он использовал объект this , который передается плагину, вместо жестко заданного селектора. Это также позволяет конвертировать не один, а несколько элементов select одновременно;

3. Код JavaScript и CSS нужно поместить в разные файлы, чтобы их было проще подключать и редактировать.

Код

Как вы помните из руководства, наш jQuery код сканирует элементы option тега select и создает неупорядоченный список. Одновременно с этим он также ищет ряд data- атрибутов в тегах option , которые содержат URL на изображение и описание для использования в элементах списка.

Это слишком специфично для плагина. Пользователям нужно дать возможность переписать эту функциональность. Для решения этой проблемы можно позволить пользователям передавать плагину функцию в качестве параметра, которая и будет генерировать разметку. Если такой параметр не передается, будем обращаться к тому, который стоит по умолчанию, и который просто берет текст элемента option и превращает его в пункт списка.

Превратим вышесказанное в код:

  • ",{ html: option.text() }); }, className: "" },options); // More code will be added here. } })(jQuery);

    Функция render берет элемент option (который находится в select) и возвращает элемент li , который подключается плагином к выпадающему списку. Это решает описанную выше проблему № 1.

    Прежде чем обратиться к проблеме № 2, давайте посмотрим, как плагин будет вызываться:

    $(document).ready(function(){ $("select").tzSelect(); });

    В приведенном выше коде вы можете видеть, что плагин применяется к каждому элементу select . Получить доступ к этим элементам можно при помощи объекта this , который передается плагину.

    Return this.each(function(){ // ключевое слово "this" это текущий элемент select var select = $(this); // selectBoxContainer - блок обертка для ul var selectBoxContainer = $("

      ",{className:"dropDown"}); var selectBox = selectBoxContainer.find(".selectBox"); // Цикл по тегам option оригинального тега select if(options.className){ dropDown.addClass(options.className); } select.find("option").each(function(i){ var option = $(this); if(i==select.attr("selectedIndex")){ selectBox.html(option.text()); } // Так как у нас jQuery 1.4.3 то получить доступ к атрибуту // HTML5 data можно при помощи метода data()) if(option.data("skip")){ return true; } // создаем выпадающий список, согласно атрибутам HTML5 // data-icon и data-html-text var li = options.render(option); li.click(function(){ selectBox.html(option.text()); dropDown.trigger("hide"); // При клике отражаем изменения на оригинальное // элементе 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; }); // Если произошел клик где-нибудь на странице при // открытом выпадающем списке, то скрываем его: $(document).click(function(){ dropDown.trigger("hide"); }); });

      Показанный выше фрагмент почти идентичен коду руководства, который мы сегодня конвертируем. Единственное заметное отличие – мы присваиваем $(this) переменной select (строка5), раньше же это был $("select.makeMeFancy") (жёстко запрограммированный селектор), что значительно сужало область действия кода.

      Другое изменение – вместо непосредственного генерирования выпадающего списка (dropdown), мы вызываем функцию render, которую мы передали как параметр (строка51).

      Собрав все воедино, мы получим полный исходный код плагина:

      (function($){ $.fn.tzSelect = function(options){ options = $.extend({ render: function(option){ return $("

    • ",{ html: option.text() }); }, className: "" },options); return this.each(function(){ // ключевое слово "this" это текущий элемент select var select = $(this); // selectBoxContainer - блок обертка для ul var selectBoxContainer = $("
      ",{ width: select.outerWidth(), className: "tzSelect", html: "
      " }); // dropDown - выпадающее меню var dropDown = $("
        ",{className:"dropDown"}); var selectBox = selectBoxContainer.find(".selectBox"); // Цикл по тегам option оригинального тега select if(options.className){ dropDown.addClass(options.className); } select.find("option").each(function(i){ var option = $(this); if(i==select.attr("selectedIndex")){ selectBox.html(option.text()); } // Так как у нас jQuery 1.4.3 то получить доступ к атрибуту // HTML5 data можно при помощи метода data()) if(option.data("skip")){ return true; } // создаем выпадающий список, согласно атрибутам HTML5 // data-icon и data-html-text var li = options.render(option); li.click(function(){ selectBox.html(option.text()); dropDown.trigger("hide"); // При клике отражаем изменения на оригинальное // элементе 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; }); // Если произошел клик где-нибудь на странице при // открытом выпадающем списке, то скрываем его: $(document).click(function(){ dropDown.trigger("hide"); }); }); } })(jQuery);

        Проблему № 3 решаем, поместив этот плагин в отдельный файл. Однако, как я упоминал ранее, мы сознательно не включили код, который содержит data- атрибуты, чтобы сделать плагин более мобильным. Чтобы компенсировать это, нужно при вызове плагина передавать пользовательскую функцию render , как вы можете увидеть ниже (этот код также используется в демо).

        $(document).ready(function(){ $("select.makeMeFancy").tzSelect({ render: function(option){ return $("

      • ",{ html: ""+ option.data("html-text")+"" }); }, className: "hasDetails" }); // вызываем версию по умолчанию $("select.regularSelect").tzSelect(); });

        Вы можете использовать этот плагин, бросив папку tzSelect в корневую директорию и включив jquery.tzSelect.css и jquery.tzSelect.js в свои HTML документы.

        Здравствуйте, хабраюзеры и просто читающие. Сравнительно недавно задался вопросом, как применить стили к тегу 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, можно ознакомиться



        просмотров