Javascript.RU

Украшалки на jQuery#1

Здесь будет описано создание маленького расширения для небезызвестного фреймворка jQuery. А делается это ради практического познания этого инструмента. Важно помнить, что это лишь первые мои jquery-шаги, так что писать будем не самое серьезное и совсем несложное. http://javascript.ru/paste/4afafb82 (неоконченный вариант. Особо про картинки не ругайтесь)

И так, пишем украшалку, применяемую к картинке. Картинка будет меняться при определенных действиях, например, при активности со ссылкой.

Первым делом нужна рабочая функция, чтобы красивенько так(через прозрачность) менять рисунок. Функция будет состоять из цепочки вызовов, причем менять ссылку на картинку нужно внутри этой цепочки. Итог поиска такой возможности - функция queue и её пара dequeue.

var change = function(img,src){
	$(img).fadeOut().queue(function(){
		this.src=src; $(this).dequeue();
	}).fadeIn();
};

вот. кажется меняется, причем моим любимым эффектом через прозрачность.
но, пишем плагин, так что вот.

jQuery.fn.blindImage = function(ch){//название "в тему"
	var _imageJQ = this;//это специфика замыканий
	var change = function(src){//собственно меняющая функция
		$(_imageJQ).fadeOut().queue(function(){
			this.src=src; $(this).dequeue();
		}).fadeIn();
	};
	return change;
}

написано через замыкания, иначе не умею.
теперь, написав $('#Картинка').blinImage(), мы получаем функцию, применяя которую будет меняться #Картинка.
То есть нужно указатель на функцию сохранить.

var f = $('#Картинка').blinImage();
/* много действий */
f('ссылка/на_другую/картинку.вот')

Погоняв скрипт оказалось, что происходят лишние "мигания", когда картинка не меняется. Поэтому добавляем проверку на равенство входящей ссылки с имеющейся.

jQuery.fn.blindImage = function(ch){
	var _imageJQ = this;
	var _src = '';//предыдущая ссылка
	
	var change = function(src){
		if(_src==src)return;//проверка
		$(_imageJQ).fadeOut().queue(function(){
			_src = this.src = src;//ставим новую "предыдущую" ссылку
			$(this).dequeue();
		}).fadeIn();
	};
	return change;
}

А вот здесь нас поджидает неприятное недоразумение. Если вызывать функцию очень часто, а порой подряд, то придется долго ждать, пока картинка завершит мигать. Особо заметно, когда проводим мышкой быстро и несколько раз по столбцу из ссылок (обычно это меню), за-onmouseover-енных на мигание картинки.

<img id="Imga" src="default.png" style="float:left;">
<a href="" name="news">news</a><br />
<a href="" name="haha">haha</a><br />
<a href="" name="default">default</a><br />
<a href="" name="events">events</a><br />

<script type="text/javascript">
var f = $('#Imga').blindImage();
$('a').mouseover(function(){ f(this.name+'.png'); });
</script>

Для устранения(частичного?) сделаем следующее. Каждый вызов функции "мигнуть" будем откладывать на короткое время. Если в это время произойдет еще один вызов, то отложенное отменяем, а текущий вызов также откладываем.

jQuery.fn.blindImage = function(ch){
	var _imageJQ = this;
	var _waiter; // будем ожидать
	var _src = '';
	
	var change = function(src){
		if(_src==src)return;
		$(_imageJQ).fadeOut().queue(function(){
			_src = this.src = src;
			$(this).dequeue();
		}).fadeIn();
	};
	var prechange = function(src){
		clearTimeout(_waiter);
		_waiter = setTimeout(function(){ change(src) }, 300);
	}
	return prechange;
}

В принципе, украшалка завершена. Но добавлю еще кое-что с дефолт-значением. В контексте применения к какой-нибудь менюшке нужно, чтобы картинка менялась не только при наведении на пункты менюшки, но и при уводе(onmouseout) картинка менялась на картинку "по умолчанию"; и установка дефолтной картинки при клике.

jQuery.fn.blindImage = function(){
	var _imageJQ;
	var _waiter;
	var _src = '';
	var _default;//значение "по умолчанию"

	this.queue(function(){_imageJQ = this; _default = this.src; }).dequeue();
	// здесь ставим дефолтное значение.
// в ходе экспериментов установлено, что это реально действенный способ,
// нежели без применения вложенной функции

	var change = function(src){
		if(!src)src = _default;//если пришло "пусто", то ставим "по умолчанию"
		if(_src==src)return;
		$(_imageJQ).fadeOut().queue(function(){
			_src = this.src = src;
			$(this).dequeue();
		}).fadeIn();
	};
	var prechange = function(src,mkdflt){
		if(mkdflt)_default = src;//флажок на установку нового значения "по умолчанию"
		clearTimeout(_waiter);
		_waiter = setTimeout(function(){ change(src) }, 300);
	};
	return prechange;
}


// а это пример использования на том самом гипотетическом меню
var f = $('#Imga').blindImage(["массив","из_ссылок","на","картинки"]);
$('a')
	.mouseover(function(){ f(this.name+'.png'); })
	.mouseout(function(){ f(0); })//внимательно!! 
// если прописать mouseout(f), то параметром пойдет event,
// а это уже не пусто,
// и вместо строковой ссылки получим что-то некорректное
	.click(function(){ f(this.name+'.png',true); return false; })
	// ложный возврат чтоб ссылка не срабатывала

+добавил немного кэширования

0

Автор: Гость (не зарегистрирован), дата: 11 ноября, 2009 - 18:54
#permalink
<script type="text/javascript">
var f = $('#Imga').blindImage();
$('a').mouseover(function(){ f('this.name+'.png'); });
</script>

это работать не будет. лишняя кавычка тут f('this.name+'.png');


Автор: Koc, дата: 11 ноября, 2009 - 19:02
#permalink

Мы все - поколение одного клика. Поэтому статьи, в которых нет ссылок на "Демо" представляют намного меньший интерес.


Автор: haha, дата: 11 ноября, 2009 - 19:30
#permalink

Действительно, забыл демку.


Автор: Гость (не зарегистрирован), дата: 26 января, 2011 - 17:32
#permalink

а демка будет?


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
8 + 0 =
Введите результат. Например, для 1+3, введите 4.
 
Поиск по сайту
Другие записи этого автора
Больше записей нет. Прокомментируйте эту запись - может быть, тогда он что-нибудь еще хорошее напишет ;)
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Популярные таги
Последние комментарии
Последние темы на форуме
Forum