Своё оформление 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‘ов. Плагин только отражает изменение значения данного свойства. Меньше звеньев в цепи — меньше погрешность (вероятность ошибки).