Как обычно все началось из-за отсутствия или плохого поиска, или не полной реализации того что мне было необходимо.
А необходимы мне были кастомные radio и checkbox'ы которые я смог бы применять в своей повседневной работе при верстке. При этом они должны были бы работать в IE6+ и всех основных браузерах.
Также элементы должны были реагировать по клику на лейбл. И еще одно их могло быть на 1 странице сколько угодно с разными стилями(да иногда случаются такие мего дизайны).
Поэтому я решил взять все лучшее, что встречал в реализациях чекбоксов и радиобатонов на JS. И написать свой плагин jQuery который удовлетворял бы мои потребности.
Вид элементов реализовывался с помощью спрайта с 4 состояниями:
— неактивный вид;
— неактивный мышь нажата;
— активный;
— активный мышь нажата.

Т.к. придется работать со спрайтом то необходимо знать смешения по вертикали картинок в нем. Для этого необходимо передавать в плагин высоту элемента, а в спрайте расположить их так чтоб они занимали одинаковое по высоте пространство.
Также необходимо чтоб при вызове плагина передавался класс, через который я смогу стилизовать элемент.
После первоначальной реализации я понял, что необходимы еще пару условий, без которых плагин будет работать некорректно. Это возможность смены состояний элементов(актинвный/неактивный) и стилизация динамически созданных элементов.
Приведу для начала весь код плагина:
Начал я с реализации структуры плагина, а вид она имеет такой:
Можно встретить такое описание выше напечатанного — «используется для создания типичного дополнения jQuery".
Начнём с конца:
В принципе в комментариях к коду все описано, могу добавить лишь
использую для того чтоб знать стилизован уже элемент или нет(конечно можно и через родителя узнать но я решил протестировать такой вот метод).
Здесь сохраняю высоту элемента т.к. элементов у меня с различными спрайтами может быть сколько угодно.
Тоже интересный метод, привязывается на кастомное событие «custom.refresh» вызов функции refresh.
Например изменилось состояние элемента на неактивное, тогда необходимо изменить вид элементы и снять все события с него.
Например:
элемент стал неактивен и произошло события «custom.refresh» благодаря которому выполнилась функция refresh.
Далее идут функции которые описаны в этой части:
Функция pushed — ставит смещение в спрайте для активного и неактивного вида, она довольно простая:
Фукция check:
Также все довольно ясно из комментариев в коде добавлю лишь об этом
.attr('checked', false).change() — необходимо чтоб событие change() файрилось и атрибут checked был изменен. Пришлось поискать это на stackoverflow.
Функция Update:
Тут не вышло обойтись без переменной, куда можно было б сохранить все элементы, на которых вызывается плагин($.CustomData.elements). Описывается она выше $.fn.extend({...})
и при вызове плагина в нее помещается набор элементов
И последняя функция, которая необходима при изменении состояния элемента refresh:
Довольно простая в понимании, просто снимаем обработчики или добавляем вновь и дописываем/убираем класс «disabled», через который можно задать вид элемента в неактивном состоянии(обычно прозрачность меняют).
Пример класса с описанием вида радиобатона:
Вызов плагина:
Надеюсь это поможет таким как я в написании своих первых плагинов на jQuery.
Это все о чем я хотел поведать в связи со своими плохими поисками нужного мне плагина. Благодарю хорошего человека Андрея за помощь в познании jQuery и написании плагина а также разработчика вот этого плагина http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/ за то что он был на js и не до конца допилен, дав мне возможность для написания своего с необходимыми мне фишками. Буду рад коментам и критике для улучшения работы плангина.
Плагин тут https://github.com/n0r8/Custom-radio-checkbox
А необходимы мне были кастомные radio и checkbox'ы которые я смог бы применять в своей повседневной работе при верстке. При этом они должны были бы работать в IE6+ и всех основных браузерах.
Также элементы должны были реагировать по клику на лейбл. И еще одно их могло быть на 1 странице сколько угодно с разными стилями(да иногда случаются такие мего дизайны).
Поэтому я решил взять все лучшее, что встречал в реализациях чекбоксов и радиобатонов на JS. И написать свой плагин jQuery который удовлетворял бы мои потребности.
Вид элементов реализовывался с помощью спрайта с 4 состояниями:
— неактивный вид;
— неактивный мышь нажата;
— активный;
— активный мышь нажата.

Т.к. придется работать со спрайтом то необходимо знать смешения по вертикали картинок в нем. Для этого необходимо передавать в плагин высоту элемента, а в спрайте расположить их так чтоб они занимали одинаковое по высоте пространство.
Также необходимо чтоб при вызове плагина передавался класс, через который я смогу стилизовать элемент.
После первоначальной реализации я понял, что необходимы еще пару условий, без которых плагин будет работать некорректно. Это возможность смены состояний элементов(актинвный/неактивный) и стилизация динамически созданных элементов.
Приведу для начала весь код плагина:
(function ($) { $.CustomData = { elements:$() }; $.fn.extend({ Custom:function (options) { var elements = this; $.CustomData.elements = $.CustomData.elements.add(elements); /*Дефолтные значения параметров*/ var defaults = { customStyleClass:"checkbox", customHeight:"16" }; /*Заменяем дефолтные опции на переданные если таковые есть*/ options = $.extend(defaults, options); /*Вид при нажатии на активный и неактивный элементы*/ var pushed = function () { var element = $(this).children('input'); if (element.is(':checked')) { /*смещения в спрайте*/ $(this).css('backgroundPosition', "0px -" + options.customHeight * 3 + "px"); } else { $(this).css('backgroundPosition', "0px -" + options.customHeight + "px"); } }; /*Отмечаем нажатый елемент все остальные сбрасываем, если они в групе(radio)*/ var check = function () { var element = $(this).children('input'); if (element.is(':checked') && element.attr('type') === 'checkbox') {/*Отмеченный чекбокс*/ $(this).css('backgroundPosition', '0px 0px'); $(this).children('input').attr('checked', false).change(); /*Меняем атрибут на неотмеченный и вызываем событие смены состояния элемента*/ } else { if (element.attr('type') === 'checkbox') {/*Неотмеченный чекбокс*/ $(this).css('backgroundPosition', "0px -" + options.customHeight * 2 + "px"); } else { /*Радиобатоны*/ $(this).css('backgroundPosition', "0px -" + options.customHeight * 2 + "px"); $('input[name=' + element.attr('name') + ']').not(element).parent().css('backgroundPosition', '0px 0px'); } $(this).children('input').attr('checked', 'checked').change(); } }; /*Обновление картинки при клике по лейблу и загрузке документа*/ var update = function () { $.CustomData.elements.each(function () { /*Проходим по всем елементам и проверяем их состояние*/ if ($(this).is(':checked')) { $(this).parent().css('backgroundPosition', "0px -" + $(this).attr('data-height') * 2 + "px"); } else { $(this).parent().css('backgroundPosition', "0px 0px"); } }); }; /*Обновление при изменении состояния disabled/enabled */ var refresh = function () { if (!$(this).prop('disabled')) { $(this).parent().mousedown(pushed); $(this).parent().mouseup(check); $(this).parent().removeClass('disabled'); } else { $(this).parent().addClass('disabled'); $(this).parent().unbind('mousedown', pushed); $(this).parent().unbind('mouseup', check); } }; return this.each(function () { if ($(this).attr('data-init') != '1') { $(this).attr('data-init', '1'); $(this).attr('data-height', options.customHeight); /*Оборачиваем в <span></span>*/ $(this).wrap('<span/>'); /*Приписываем класс оформления переданный в параметрах*/ var span = $(this).parent().addClass(options.customStyleClass); if ($(this).is(':checked') === true) { /*Задаем картинку еси элемент отмечен*/ span.css('backgroundPosition', "0px -" + (options.customHeight * 2) + "px"); } /*Бинд на изменение состояния элемента и кастомное событие для обновления после программного изменения состояния кнопки*/ $(this).bind('change', update); $(this).bind('custom.refresh', refresh); if (!$(this).prop('disabled')) { /*Бинд функций на span*/ span.mousedown(pushed); span.mouseup(check); } else { /*Добавление класса если элемент неактивен*/ span.addClass('disabled'); } } }); } }); })(jQuery);
Начал я с реализации структуры плагина, а вид она имеет такой:
(function ($) { $.fn.extend({ Custom:function (options) { /*Дефолтные значения параметров*/ var defaults = { customStyleClass:"checkbox", customHeight:"16" }; /*Заменяем дефолтные опции на переданные если таковые есть*/ options = $.extend(defaults, options); }; return this.each(function () { }); } });
Можно встретить такое описание выше напечатанного — «используется для создания типичного дополнения jQuery".
Начнём с конца:
return this.each(function () { if ($(this).attr('data-init') != '1') { $(this).attr('data-init', '1'); $(this).attr('data-height', options.customHeight); /*Оборачиваем в <span></span>*/ $(this).wrap('<span/>'); /*Приписываем класс оформления переданный в параметрах*/ var span = $(this).parent().addClass(options.customStyleClass); if ($(this).is(':checked') === true) { /*Задаем картинку еси элемент отмечен*/ span.css('backgroundPosition', "0px -" + (options.customHeight * 2) + "px"); } /*Бинд на изменение состояния элемента и кастомное событие для обновления после программного изменения состояния кнопки*/ $(this).bind('change', update); $(this).bind('custom.refresh', refresh); if (!$(this).prop('disabled')) { /*Бинд функций на span*/ span.mousedown(pushed); span.mouseup(check); } else { /*Добавление класса если элемент неактивен*/ span.addClass('disabled'); } } });
В принципе в комментариях к коду все описано, могу добавить лишь
$(this).attr('data-init', '1');
использую для того чтоб знать стилизован уже элемент или нет(конечно можно и через родителя узнать но я решил протестировать такой вот метод).
$(this).attr('data-height', options.customHeight);
Здесь сохраняю высоту элемента т.к. элементов у меня с различными спрайтами может быть сколько угодно.
$(this).bind('custom.refresh', refresh);
Тоже интересный метод, привязывается на кастомное событие «custom.refresh» вызов функции refresh.
Например изменилось состояние элемента на неактивное, тогда необходимо изменить вид элементы и снять все события с него.
Например:
$('#radio3').removeAttr('disabled').trigger('custom.refresh');
элемент стал неактивен и произошло события «custom.refresh» благодаря которому выполнилась функция refresh.
Далее идут функции которые описаны в этой части:
Custom:function (options) {...};
Функция pushed — ставит смещение в спрайте для активного и неактивного вида, она довольно простая:
var pushed = function () { var element = $(this).children('input'); if (element.is(':checked')) { /*смещения в спрайте*/ $(this).css('backgroundPosition', "0px -" + options.customHeight * 3 + "px"); } else { $(this).css('backgroundPosition', "0px -" + options.customHeight + "px"); } };
Фукция check:
/*Отмечаем нажатый элемент все остальные сбрасываем, если они в группе (radio)*/ var check = function () { var element = $(this).children('input'); if (element.is(':checked') && element.attr('type') === 'checkbox') {/*Отмеченный чекбокс*/ $(this).css('backgroundPosition', '0px 0px'); $(this).children('input').attr('checked', false).change(); /*Меняем атрибут на неотмеченный и вызываем событие смены состояния элемента*/ } else { if (element.attr('type') === 'checkbox') {/*Неотмеченный чекбокс*/ $(this).css('backgroundPosition', "0px -" + options.customHeight * 2 + "px"); } else { /*Радиобатоны*/ $(this).css('backgroundPosition', "0px -" + options.customHeight * 2 + "px"); $('input[name=' + element.attr('name') + ']').not(element).parent().css('backgroundPosition', '0px 0px'); } $(this).children('input').attr('checked', 'checked').change(); } };
Также все довольно ясно из комментариев в коде добавлю лишь об этом
$(this).children('input').attr('checked', false).change();
.attr('checked', false).change() — необходимо чтоб событие change() файрилось и атрибут checked был изменен. Пришлось поискать это на stackoverflow.
Функция Update:
/*Обновление картинки при клике по лейблу*/ var update = function () { $.CustomData.elements.each(function () { /*Проходим по всем елементам и проверяем их состояние*/ if ($(this).is(':checked')) { $(this).parent().css('backgroundPosition', "0px -" + $(this).attr('data-height') * 2 + "px"); } else { $(this).parent().css('backgroundPosition', "0px 0px"); } }); };
Тут не вышло обойтись без переменной, куда можно было б сохранить все элементы, на которых вызывается плагин($.CustomData.elements). Описывается она выше $.fn.extend({...})
$.CustomData = { elements:$() };
и при вызове плагина в нее помещается набор элементов
var elements = this; $.CustomData.elements = $.CustomData.elements.add(elements);
И последняя функция, которая необходима при изменении состояния элемента refresh:
/*Обновление при изменении состояния disabled/enabled */ var refresh = function () { if (!$(this).prop('disabled')) { $(this).parent().mousedown(pushed); $(this).parent().mouseup(check); $(this).parent().removeClass('disabled'); } else { $(this).parent().addClass('disabled'); $(this).parent().unbind('mousedown', pushed); $(this).parent().unbind('mouseup', check); } };
Довольно простая в понимании, просто снимаем обработчики или добавляем вновь и дописываем/убираем класс «disabled», через который можно задать вид элемента в неактивном состоянии(обычно прозрачность меняют).
Пример класса с описанием вида радиобатона:
.radio { display:block; height: 25px; width: 19px; overflow:hidden; background: url("radio.png") no-repeat 0 0 transparent; position:relative; } .radio.disabled{ opacity:0.5; filter:Alpha(opacity="50"); } .radio input{ position:absolute; right:-400px; top:0px; }
Вызов плагина:
$("input[type='radio']").Custom({ customStyleClass:'radio', customHeight:'25' });
Надеюсь это поможет таким как я в написании своих первых плагинов на jQuery.
Это все о чем я хотел поведать в связи со своими плохими поисками нужного мне плагина. Благодарю хорошего человека Андрея за помощь в познании jQuery и написании плагина а также разработчика вот этого плагина http://ryanfait.com/resources/custom-checkboxes-and-radio-buttons/ за то что он был на js и не до конца допилен, дав мне возможность для написания своего с необходимыми мне фишками. Буду рад коментам и критике для улучшения работы плангина.
Плагин тут https://github.com/n0r8/Custom-radio-checkbox
