Совершенствуем принцип отображения элементов «select» посредством jQuery и CSS3
При создании веб-дизайнов, разработчики всегда стремятся добиться оптимального отображения веб-сайта во всех браузерах. К сожалению, одним из основных элементов веб-сайта являются настройки браузера, к тому же, это значительно усложняет процесс оформления. Некоторые из спецификаций браузеров (например, элементы форм «select») вообще невозможно изменить, за исключением некоторых случаев.
По этой причине сегодня мы хотим поделиться с вами скриптом, который поможет нам заменить простой элемент «select» на более привлекательный, оставив полностью весь функционал.
HTML
Как и обычно, начнем с разработки HTML-кода. Мы будем использовать разметку HTML5, так как это даст нам некоторое преимущество (например, возможность вносить атрибуты данных, с помощью которых мы можем в целом дополнить разметку страницу.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Making Better Select Elements with jQuery and CSS3</title>
<link rel="stylesheet" type="text/css" href="css/styles.css" />
</head>
<body>
<div id="page">
<h1>Your Product</h1>
<form method="post" action="">
<select name="fancySelect" class="makeMeFancy">
<option value="0" selected="selected" data-skip="1">Choose Your Product</option>
<option value="1" data-icon="img/products/iphone.png" data-html-text="iPhone 4<i>in stock</i>">iPhone 4</option>
<option value="2" data-icon="img/products/ipod.png" data-html-text="iPod <i>in stock</i>">iPod</option>
<option value="3" data-icon="img/products/air.png" data-html-text="MacBook Air<i>out of stock</i>">MacBook Air</option>
<option value="4" data-icon="img/products/imac.png" data-html-text="iMac Station<i>in stock</i>">iMac Station</option>
</select>
</form>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>
В коде можно заметить, что мы применяем атрибуты данных ко встроенной информации и в элементах опций «select». Мы вносим иконку продукта и богатое текстовое описание. Всё это будет отображено в усовершенствованной версии элемента «select».
Мы также внесли дополнительный атрибут data-skip к первому элементу, так что наш скрипт знает, чего ему не нужно включать в сгенерированный список. Можно просто проверить наличие атрибутов data-icon и data-html-text и пропустить элемент, если это потребуется.
В нижней части документа включён jQuery версии 1.4.3 (последняя версия библиотеки на момент написания этой статьи), а также наш script.js. Об этом мы расскажем в следующем этапе разработки.
jQuery
При событии document.ready, jQuery проверяет элемент «select» и, используя атрибуты данных, создаёт разметку, которую вы можете видеть ниже, которая появляется сразу же после «select»:
<div style="width: 144px;" class="tzSelect">
<div class="selectBox">iMac Station</div>
<ul class="dropDown">
<li><img src="img/products/iphone.png"><span>iPhone 4<i>in stock</i></span></li>
<li><img src="img/products/ipod.png"><span>iPod <i>in stock</i></span></li>
<li><img src="img/products/air.png"><span>MacBook Air<i>out of stock</i></span></li>
<li><img src="img/products/imac.png"><span>iMac Station<i>in stock</i></span></li>
</ul>
</div>
Как видно, мы создаём неупорядоченный список с элементом li, который представляет каждую опцию в «select». Сама форма «select» представлена посредством div’а с классом .selectBox.
Теперь давайте поближе взглянем на сгенерированный код.
$(document).ready(function(){
// The select element to be replaced:
var select = $('select.makeMeFancy');
var selectBoxContainer = $('<div>',{
width : select.outerWidth(),
className : 'tzSelect',
html : '<div class="selectBox"></div>'
});
var dropDown = $('<ul>',{className:'dropDown'});
var selectBox = selectBoxContainer.find('.selectBox');
// Looping though the options of the original select element
select.find('option').each(function(i){
var option = $(this);
if(i==select.attr('selectedIndex')){
selectBox.html(option.text());
}
// As of jQuery 1.4.3 we can access HTML5
// data attributes with the data() method.
if(option.data('skip')){
return true;
}
// Creating a dropdown item according to the
// data-icon and data-html-text HTML5 attributes:
var li = $('<li>',{
html: '<img src="'+option.data('icon')+'" /><span>'+
option.data('html-text')+'</span>'
});
li.click(function(){
selectBox.html(option.text());
dropDown.trigger('hide');
// When a click occurs, we are also reflecting
// the change on the original select element:
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Binding custom show and hide events on the 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;
});
// If we click anywhere on the page, while the
// dropdown is shown, it is going to be hidden:
$(document).click(function(){
dropDown.trigger('hide');
});
});
При полной загрузке страницы, скрипт сканирует опции элемента «select» и генерирует разметку в соответствии с атрибутами данных в HTML5, которые содержат эти пункты. Что касается jQuery версии 1.4.3, то посредством этой версии мы имеем доступ к значениям этих атрибутов напрямую при помощи метода data(). Это очень удобная функция, которая значительно упрощает процесс считывания встроенных данных.
Стандартный элемент «select» не уничтожается – он просто скрывается посредством метода hide(). Это важно, потому что, как вы можете видеть в коде выше, нам нужно отражать любые изменения в форме на стандартный элемент «select». Таким образом, когда вы используете «select» в качестве части формы, значения считываются правильно, а затем передаются в базу данных.
Теперь, когда наш код на месте, давайте подробнее рассмотрим CSS3.
CSS-код
Как видно из разметки в верхней части предыдущего этапа, мы используем лишь немного кода для отображения поля «select» и выпадающий список. Если мы захотим использовать методики, бывшие в употреблении до прихода CSS3, то нам придётся добавить намного больше div’ов и span’ов.
#page{
width:230px;
margin:100px auto;
}
#page h1{
font-weight:normal;
text-indent:-99999px;
overflow:hidden;
background:url('../img/your_product.png') no-repeat;
width:230px;
height:36px;
}
#page form{
margin:20px auto;
width:200px;
}
.tzSelect{
/* This is the container of the new select element */
height:34px;
display:inline-block;
min-width:200px;
position:relative;
/* Preloading the background image for the dropdown */
background:url("../img/dropdown_slice.png") no-repeat -99999px;
}
.tzSelect .selectBox{
position:absolute;
height:100%;
width:100%;
/* Font settings */
font:13px/34px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
text-align:center;
text-shadow:1px 1px 0 #EEEEEE;
color:#666666;
/* Using CSS3 multiple backgrounds and a fallback */
background:url('../img/select_slice.png') repeat-x #ddd;
background-image:url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png');
background-position:0 -136px, right -204px, 50% -68px, 0 0;
background-repeat: no-repeat, no-repeat, no-repeat, repeat-x;
cursor:pointer;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
}
.tzSelect .selectBox:hover,
.tzSelect .selectBox.expanded{
background-position:0 -170px, right -238px, 50% -102px, 0 -34px;
color:#2c5667;
text-shadow:1px 1px 0 #9bc2d0;
}
CSS3 позволяет нам задавать различные фоновые изображения к элементам путем добавления множественных объявлений url(), разделённых запятыми. Они добавляются к элементу сверху вниз последовательно, с отдельными изображениями фона, отображенными под каждым пунктом.
На данный момент множественные фоновые изображения поддерживаются в браузерах Firefox, Safari, Chrome и Opera. Что касается Internet Explorer и ранних версий других браузеров, то здесь имеется версия для отката, т.е. задействуется стандартное фоновое изображение. Когда браузеры парсят CSS-документ, те браузеры, которые не распознают множественные фоновые изображения, будут просто игнорировать правило и использовать одно из них.
Параметр box-sizing, который мы использовали для класса .dropDown, определяет то, как границы добавляются к общему размеру элемента. По умолчанию, здесь границы будут увеличивать общую ширину на 2 пикселя, что отрицательно скажется на выравнивании. С установленным параметром box-sizing, тем не менее, общая ширина не будет превышать заранее установленную отметку, и поэтому браузеры будут использовать пространство внутри элемента.
На этом наше поле «select» на jQuery и CSS3 закончено!
Напоследок
В этой статье мы продемонстрировали некоторые полезные функции, представленные в jQuery версии 1.4.3, а также некоторые возможности CSS3. Следует отметить то, что данный скрипт сохраняет стандартное поле «select» скрытым на странице, а его значения изменяются посредством хитрости. Таким образом, когда вы подтверждаете хитрый «select», корректное значение также предоставляется на обработку.
По этой причине сегодня мы хотим поделиться с вами скриптом, который поможет нам заменить простой элемент «select» на более привлекательный, оставив полностью весь функционал.
HTML
Как и обычно, начнем с разработки HTML-кода. Мы будем использовать разметку HTML5, так как это даст нам некоторое преимущество (например, возможность вносить атрибуты данных, с помощью которых мы можем в целом дополнить разметку страницу.
Код
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Making Better Select Elements with jQuery and CSS3</title>
<link rel="stylesheet" type="text/css" href="css/styles.css" />
</head>
<body>
<div id="page">
<h1>Your Product</h1>
<form method="post" action="">
<select name="fancySelect" class="makeMeFancy">
<option value="0" selected="selected" data-skip="1">Choose Your Product</option>
<option value="1" data-icon="img/products/iphone.png" data-html-text="iPhone 4<i>in stock</i>">iPhone 4</option>
<option value="2" data-icon="img/products/ipod.png" data-html-text="iPod <i>in stock</i>">iPod</option>
<option value="3" data-icon="img/products/air.png" data-html-text="MacBook Air<i>out of stock</i>">MacBook Air</option>
<option value="4" data-icon="img/products/imac.png" data-html-text="iMac Station<i>in stock</i>">iMac Station</option>
</select>
</form>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script src="js/script.js"></script>
</body>
</html>
В коде можно заметить, что мы применяем атрибуты данных ко встроенной информации и в элементах опций «select». Мы вносим иконку продукта и богатое текстовое описание. Всё это будет отображено в усовершенствованной версии элемента «select».
Мы также внесли дополнительный атрибут data-skip к первому элементу, так что наш скрипт знает, чего ему не нужно включать в сгенерированный список. Можно просто проверить наличие атрибутов data-icon и data-html-text и пропустить элемент, если это потребуется.
В нижней части документа включён jQuery версии 1.4.3 (последняя версия библиотеки на момент написания этой статьи), а также наш script.js. Об этом мы расскажем в следующем этапе разработки.
jQuery
При событии document.ready, jQuery проверяет элемент «select» и, используя атрибуты данных, создаёт разметку, которую вы можете видеть ниже, которая появляется сразу же после «select»:
Код
<div style="width: 144px;" class="tzSelect">
<div class="selectBox">iMac Station</div>
<ul class="dropDown">
<li><img src="img/products/iphone.png"><span>iPhone 4<i>in stock</i></span></li>
<li><img src="img/products/ipod.png"><span>iPod <i>in stock</i></span></li>
<li><img src="img/products/air.png"><span>MacBook Air<i>out of stock</i></span></li>
<li><img src="img/products/imac.png"><span>iMac Station<i>in stock</i></span></li>
</ul>
</div>
Как видно, мы создаём неупорядоченный список с элементом li, который представляет каждую опцию в «select». Сама форма «select» представлена посредством div’а с классом .selectBox.
Теперь давайте поближе взглянем на сгенерированный код.
Код
$(document).ready(function(){
// The select element to be replaced:
var select = $('select.makeMeFancy');
var selectBoxContainer = $('<div>',{
width : select.outerWidth(),
className : 'tzSelect',
html : '<div class="selectBox"></div>'
});
var dropDown = $('<ul>',{className:'dropDown'});
var selectBox = selectBoxContainer.find('.selectBox');
// Looping though the options of the original select element
select.find('option').each(function(i){
var option = $(this);
if(i==select.attr('selectedIndex')){
selectBox.html(option.text());
}
// As of jQuery 1.4.3 we can access HTML5
// data attributes with the data() method.
if(option.data('skip')){
return true;
}
// Creating a dropdown item according to the
// data-icon and data-html-text HTML5 attributes:
var li = $('<li>',{
html: '<img src="'+option.data('icon')+'" /><span>'+
option.data('html-text')+'</span>'
});
li.click(function(){
selectBox.html(option.text());
dropDown.trigger('hide');
// When a click occurs, we are also reflecting
// the change on the original select element:
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Binding custom show and hide events on the 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;
});
// If we click anywhere on the page, while the
// dropdown is shown, it is going to be hidden:
$(document).click(function(){
dropDown.trigger('hide');
});
});
При полной загрузке страницы, скрипт сканирует опции элемента «select» и генерирует разметку в соответствии с атрибутами данных в HTML5, которые содержат эти пункты. Что касается jQuery версии 1.4.3, то посредством этой версии мы имеем доступ к значениям этих атрибутов напрямую при помощи метода data(). Это очень удобная функция, которая значительно упрощает процесс считывания встроенных данных.
Стандартный элемент «select» не уничтожается – он просто скрывается посредством метода hide(). Это важно, потому что, как вы можете видеть в коде выше, нам нужно отражать любые изменения в форме на стандартный элемент «select». Таким образом, когда вы используете «select» в качестве части формы, значения считываются правильно, а затем передаются в базу данных.
Теперь, когда наш код на месте, давайте подробнее рассмотрим CSS3.
CSS-код
Как видно из разметки в верхней части предыдущего этапа, мы используем лишь немного кода для отображения поля «select» и выпадающий список. Если мы захотим использовать методики, бывшие в употреблении до прихода CSS3, то нам придётся добавить намного больше div’ов и span’ов.
Код
#page{
width:230px;
margin:100px auto;
}
#page h1{
font-weight:normal;
text-indent:-99999px;
overflow:hidden;
background:url('../img/your_product.png') no-repeat;
width:230px;
height:36px;
}
#page form{
margin:20px auto;
width:200px;
}
.tzSelect{
/* This is the container of the new select element */
height:34px;
display:inline-block;
min-width:200px;
position:relative;
/* Preloading the background image for the dropdown */
background:url("../img/dropdown_slice.png") no-repeat -99999px;
}
.tzSelect .selectBox{
position:absolute;
height:100%;
width:100%;
/* Font settings */
font:13px/34px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
text-align:center;
text-shadow:1px 1px 0 #EEEEEE;
color:#666666;
/* Using CSS3 multiple backgrounds and a fallback */
background:url('../img/select_slice.png') repeat-x #ddd;
background-image:url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png'),url('../img/select_slice.png');
background-position:0 -136px, right -204px, 50% -68px, 0 0;
background-repeat: no-repeat, no-repeat, no-repeat, repeat-x;
cursor:pointer;
-moz-border-radius:3px;
-webkit-border-radius:3px;
border-radius:3px;
}
.tzSelect .selectBox:hover,
.tzSelect .selectBox.expanded{
background-position:0 -170px, right -238px, 50% -102px, 0 -34px;
color:#2c5667;
text-shadow:1px 1px 0 #9bc2d0;
}
CSS3 позволяет нам задавать различные фоновые изображения к элементам путем добавления множественных объявлений url(), разделённых запятыми. Они добавляются к элементу сверху вниз последовательно, с отдельными изображениями фона, отображенными под каждым пунктом.
На данный момент множественные фоновые изображения поддерживаются в браузерах Firefox, Safari, Chrome и Opera. Что касается Internet Explorer и ранних версий других браузеров, то здесь имеется версия для отката, т.е. задействуется стандартное фоновое изображение. Когда браузеры парсят CSS-документ, те браузеры, которые не распознают множественные фоновые изображения, будут просто игнорировать правило и использовать одно из них.
Код
.tzSelect .dropDown{
position:absolute;
top:40px;
left:0;
width:100%;
border:1px solid #32333b;
border-width:0 1px 1px;
list-style:none;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
-moz-box-shadow:0 0 4px #111;
-webkit-box-shadow:0 0 4px #111;
box-shadow:0 0 4px #111;
}
.tzSelect li{
height:85px;
cursor:pointer;
position:relative;
/* Again, using CSS3 multiple backgrounds */
background:url('../img/dropdown_slice.png') repeat-x #222;
background-image:url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png');
background-position: 50% -171px, 0 -85px, 0 0;
background-repeat: no-repeat, no-repeat, repeat-x;
}
.tzSelect li:hover{
background-position: 50% -256px, 0 -85px, 0 0;
}
.tzSelect li span{
left:88px;
position:absolute;
top:27px;
}
.tzSelect li i{
color:#999999;
display:block;
font-size:12px;
}
.tzSelect li img{
left:9px;
position:absolute;
top:13px;
}
position:absolute;
top:40px;
left:0;
width:100%;
border:1px solid #32333b;
border-width:0 1px 1px;
list-style:none;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box;
-moz-box-shadow:0 0 4px #111;
-webkit-box-shadow:0 0 4px #111;
box-shadow:0 0 4px #111;
}
.tzSelect li{
height:85px;
cursor:pointer;
position:relative;
/* Again, using CSS3 multiple backgrounds */
background:url('../img/dropdown_slice.png') repeat-x #222;
background-image:url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png'),url('../img/dropdown_slice.png');
background-position: 50% -171px, 0 -85px, 0 0;
background-repeat: no-repeat, no-repeat, repeat-x;
}
.tzSelect li:hover{
background-position: 50% -256px, 0 -85px, 0 0;
}
.tzSelect li span{
left:88px;
position:absolute;
top:27px;
}
.tzSelect li i{
color:#999999;
display:block;
font-size:12px;
}
.tzSelect li img{
left:9px;
position:absolute;
top:13px;
}
Параметр box-sizing, который мы использовали для класса .dropDown, определяет то, как границы добавляются к общему размеру элемента. По умолчанию, здесь границы будут увеличивать общую ширину на 2 пикселя, что отрицательно скажется на выравнивании. С установленным параметром box-sizing, тем не менее, общая ширина не будет превышать заранее установленную отметку, и поэтому браузеры будут использовать пространство внутри элемента.
На этом наше поле «select» на jQuery и CSS3 закончено!
Напоследок
В этой статье мы продемонстрировали некоторые полезные функции, представленные в jQuery версии 1.4.3, а также некоторые возможности CSS3. Следует отметить то, что данный скрипт сохраняет стандартное поле «select» скрытым на странице, а его значения изменяются посредством хитрости. Таким образом, когда вы подтверждаете хитрый «select», корректное значение также предоставляется на обработку.
-
FalleN -
3555 -
1 -
217
Но только нужно ставить наверное на те модули которые обновляться должны не раньше через пару тройку минут
С Уважением, Андрей...