Вот как это сделать правильно, используя прогрессивное улучшение . Идея проста: превратить прилично размеченную HTML-форму в более приятные кнопки выбора цвета и размера для пользователей, которые имеют JavaScript.
Преимущества этого метода многочисленны, вы можете легко переключать или удалять компоненты (JS / CSS) и работать с формой. Он будет работать для пользователей, которые не поддерживают javascript, и, если мы будем осторожны, он будет доступен через программы чтения с клавиатуры и экрана. Это также не требует дополнительного кода при отправке, и будет намного проще использовать с валидатором формы.
Большая часть работы выполняется с использованием CSS с минимальным JavaScript для добавления завершающих штрихов.
Полный пример работы можно найти на jsbin . Включает выбор цвета и размера. Я включил здесь только цвета, так как между ними только небольшая разница в CSS.
HTML
Прежде всего, разметьте компоненты формы. Вот основы, вы, возможно, захотите добавить что-то вроде обертки вокруг всего виджета или использовать другие имена классов.
<label>Color</label>
<ul class="radio color">
<li class="red">
<input type="radio" name="color" id="color_red" value="red" />
<label for="color_red">Red</label>
</li>
<li class="green">
<input type="radio" name="color" id="color_green" value="green" />
<label for="color_green">Green</label>
</li>
<!-- ...and so on... -->
</ul>
Это может показаться много для "основ", но здесь происходит несколько вещей. Весь контейнер UL
помечается как «радио», поэтому все внутри может быть соответствующим образом нацелено с помощью CSS ("ul.radio label"
).
Дополнительно я добавляю класс, соответствующий имени ввода, и класс для каждого LI
, повторяющего значение, чтобы CSS мог добавить соответствующие стили ("ul.color li.red"
). Остальное - в значительной степени ваша стандартная разметка форм.
JavaScript
JavaScript очень прост. Все, что мы делаем, это определяем, какой радиовход в настоящее время выбран, и помечаем контейнер LI
с помощью «выбранного» класса, что позволяет CSS выделять его соответствующим образом.
jQuery(function($){
// notify CSS that JS is present
$( 'body' ).addClass( 'js-active' );
// for every radio control...
$( 'ul.radio' )
// redo every change
.bind('click', function () {
// refresh "current classes"
$( 'li', this ).removeClass( 'selected' )
.filter( ':has(:checked)' ).addClass( 'selected' );
})
// trigger initial run
.trigger( 'click' );
});
Обратите внимание: эта «хитрость» запуска клика для обеспечения начального запуска может быть небезопасной, если у вас выше обработчики кликов (обычно document.body
), я использую этот метод для краткости.
CSS
Здесь происходит настоящее волшебство. Идея состоит в том, что мы можем убрать элементы управления вводом из вида и стилизовать метки как цветные кнопки. До тех пор, пока атрибуты for
на ярлыках правильно указывают на id
на входах, достаточно щелкнуть ярлыки, чтобы правильно выбрать элемент управления.
Нам нужно нацелиться на вещи только в пределах ".js-active"
, чтобы пользователи, у которых нет JavaScript, но все еще есть CSS, увидели элементы радиовхода. Какой-то класс ".radio-js" может быть альтернативно добавлен в оболочку UL
, чтобы сделать то же самое.
Во-первых, плавайте кнопки и придавайте им более похожий на кнопки вид:
/* attributes are lined up horizontally */
ul.color li,
ul.size li {
border : 1px solid #aaa;
margin : 0 4px 0 0;
padding : 2px;
float : left;
overflow : hidden;
position : relative;
}
Мы помещаем position:relative
и overflow:hidden
на каждую LI, чтобы мы могли сместить элемент ввода вне поля зрения. Это сделает его доступным, но нам больше не нужно смотреть на него:
/* if JS: remove inputs from sight */
.js-active ul.color input,
.js-active ul.size input {
position : absolute;
left : -999em;
}
Далее следует превратить метки в кнопки:
/* if JS: turn color labels into buttons */
.js-active ul.color label {
cursor : pointer;
display : block;
height : 18px;
width : 18px;
text-indent : -999em; /* hide text */
}
/* color buttons in color -- allowed even if no JS */
ul.color li.red label { background : red; }
ul.color li.green label { background : green; }
ul.color li.blue label { background : blue; }
Наконец, установите несколько стилей для нашего выделенного / выбранного элемента.
/* if JS: current selected highlight */
.js-active ul.color .selected,
.js-active ul.size .selected {
border : 2px solid #000;
padding : 1px;
}
Для полноты: Получение значений выбора , если вы хотите добавить больше эффектов, продемонстрировано в другом месте на SO.