Своё оформление checkbox-элементов форм — проще, чем кажется
Оказывается, это не так уж и сложно. И для этого не нужно использовать горы хаков, чтобы обеспечить кросс-браузерность.
Анализ существующих средств показал, что чаще всего используется дополнительный тэг, который «заворачивается» вокруг элемента формы и затем с ним производятся манипуляции.
У меня же задача стояла следующая.
Есть элемент формы, выглядящий следующим образом:
<div class="form-item> <label class="option" for="brands-acer"> <input name="brand_filter[brands][acer]" id="brands-acer" value="acer" type="checkbox" /> Acer (6) </label> </div>
Необходимо, чтобы он выглядел как-то так (скриншот уже готовой страницы):
Готовые решения прикручиваться не хотели, да и качеством не впечатлили, поэтому (да-да) было решено написать своё. В результате получился совсем небольшой плагин для jQuery (что меня удивило) и пара строчек CSS-кода. Работа проверена в IE 6+, FF 3.6.6, Opera 10.5+, Chrome 5.
Код плагина представлен ниже с подробными комментариями:
(function($) { $.fn.checkboxStyle = function(o) { o = $.extend({ height: 14 // высота фонового изображения }, o || {}); return this.each(function() { var checkbox = $(this); // наш input // добавляем span вокруг input'а $(checkbox).wrap('/&gt;'); // если скрыть чекбокс выставив display: none, то при клике на связанный label // значение checked меняться не будет, поэтому просто убираем его с глаз долой за пределы страницы // причем значение top здесь не указанно специально - иначе при клике на label страница // будет скролиться вверх $(checkbox).css("position", "absolute").css("left", "-999px"); // IE вызывает событие change, только после того как фокус перейдёт на другой элемент // поэтому здесь вызываем его насильно при клике по label'у $(checkbox).parents('label').css("cursor", "pointer").bind('click', function() { $(this).find("input:checkbox").change(); return true; }); // обработка самого события change: изменение положения фонового изображения $(checkbox).change(function() { var checked = $(this).attr("checked"); if (checked) { $(this).parent('.cb-styled').css("background-position", "0px -"+o.height+"px"); } else { $(this).parent('.cb-styled').css("background-position", "0px 0px"); } }); // напоследок вызываем наше событие при загрузке страницы для // инициализации режимов наших красивых чекбоксов $(checkbox).change(); }); }; })(jQuery);
В CSS были вынесены только стили, относящиеся к добавляемому span’у:
.cb-styled { float: left; width: 14px; height: 14px; margin: 2px 3px 2px 2px; } .cb-styled { background: url(../images/checkbox.gif) no-repeat 0px 0px; }
Само изображение чекбокса выполнено спрайтами:
Вызов плагина осуществляется следующим образом:
$("#category-block-form input:checkbox").checkboxStyle();
Если размер чекбокса отличается от моего примера, его можно указать при вызове, например:
$("#category-block-form input:checkbox").checkboxStyle({height: 18});
В данном примере не реализована обработка наведения мыши (mouserover) на чекбокс и нажатия (mousedown). Но, думаю, обработка двух дополнительных событий теперь не составит сложности (я же их не сделал, потому что в дизайне они не были отрисованы).
Что мне нравится в данном подходе: если обратили внимание, здесь не производится манипуляций со свойством checked
у input
‘ов. Плагин только отражает изменение значения данного свойства. Меньше звеньев в цепи — меньше погрешность (вероятность ошибки).