22 декабря 2015
10 июня 2009
30
Создаем jQuery плагин на примере поискового поля
Привет!
Сегодня я расскажу о том, как сделать jQuery плагин. А чтобы не делать что-то абстрактное, давайте сделаем вот такой плагин для текстового поля: есть текст по умолчанию и какой-то класс. При фокусе в это поле убирается класс и дефолтный текст, при блюре на нем — если ничего не введено, то текст и класс возвращаются домой. Такие штуки модные парни обычно используют для полей поиска, но они могут пригодиться нам и для других полей.
В программе урока: как делать плагин к jQuery, реализация простого плагина и аналог такого скрипта под Mootools (не все же одно jQuery).
Структура плагина
Для начала посмотрим на общую структуру плагина. Я написал комментарии к каждой строчке, так что смотрим на код:
<script type="text/javascript">
// так вот начинается описание плагина (с названием somePlugin)
(function($) {
$.fn.somePlugin = function(options) {
// значение по умолчанию для опциональных аргументов
// в виде имя: значение
var defaults = {
someOption: 'someValue'
};
// расширяем дефолтные значения опциями
var opts = $.extend(defaults, options);
// они теперь доступны как opts[имя_опции]
// вот тут сам плагин
};
})(jQuery);
</script>
Вызывается плагин следующим образом:
<script type="text/javascript">
$('my_element').somePlugin({
someOption: 'anotherValue'
});
</script>
Ну чтож, более-менее ясно, давайте перейдем к конкретике.
Плагин для текстового поля
В общем, есть у нас какое-то текстовое поле:
<input type="text" id="search-input" name="q" />
Немного стилей для красоты:
#search-input {
font-size: 3em;
width: 15em;
}
// это стиль для неактивного состояния
.inactive {
color: #AAA;
}
Сделать нам нужно вот так:
- при загрузке страницы добавить к полю класс для неактивного состояния (.inactive);
- поставить дефолтное значение («Поиск»);
- при фокусе убирать класс и обнулять значение, если там стоит слово «Поиск»;
- при блюре проверяем, если поле пустое или там стоит слово «Поиск», то добавляем класс .inactive и выставляем дефолтное значение.
Вот такая схема. Реализуется она следующим образом (смотрим комментарии в коде):
<script type="text/javascript">
(function($) {
$.fn.inputDefualts = function(options) {
// дефолтные значения
var defaults = {
cl: 'inactive', // имя класса для неактивного состояния
text: this.val() // значение берется из самого инпута
}, opts = $.extend(defaults, options);
this.addClass(opts['cl']); // добавляем класс к инпуту
this.val(opts['text']); // ставим значение по умолчанию
// обрабатываем события фокуса на поле
this.focus(function() {
if($(this).val() == opts['text']) $(this).val(''); // обнуляем его, если надо
$(this).removeClass(opts['cl']); // убираем класс
});
// теперь очередь блюра
this.blur(function() {
if($(this).val() == '') {
$(this).val(opts['text']); // возвращаем значение
$(this).addClass(opts['cl']); // и класс, если надо
}
});
};
})(jQuery);
$(document).ready(function() {
// вызов плагина
$('#search-input').inputDefualts({
cl: 'inactive',
text: 'Поиск'
});
});
</script>
Еще хотелось бы добавить на будущее - если полей будет много, то лучше немного поправить последний листинг на этот случай, добавив после перечисления дефолтных настроек $(this).each( ... ). Ведь в основном мы манипулируем наборами, а не отдельной формой.
То-же самое, 2-мя строчками обычного кода делается.
Жаль, код в кометах не привести.
PS
Хотя в целом, я обеими руками голосую и за jQuery и за Mootools.
по крайней мере я так делаю =)
необходимо добавить следующее:
намудрили то....
прошлый век, прошлый век...
в этом веке видимо модно микроскопом гвозди забивать? ))
Смотри, скажем у тебя есть проект с кучей таких полей, который разбросаны по шаблонам. Чтобы что-то поменять в твоей функции (убрать или добавить класс) нужно будет править каждый шаблон. В моем случае нужно поправить пару строчек в одном файле js.
Кроме того, инлайновая привязка событий это плохой тон.
А вообще, мое мнение что такие штуки неплохо выносить на уровень самой библиотеки. Например, так же как они сделали событие hover.
...
$.fn.inputDefaults = ...
Кстати, спасибо за полезную статью :)