Введение в jQuery (продолжение)

Введение в jQuery (продолжение)Прежде чем читать эту статью, читай Введение в jQuery. Осилил? Молодец, идем дальше.

Сегодня я начну рассказ с того, что не досказал в предыдущий раз. Не, я не жадный до своих знаний, просто не хотел разводить демагогию. Итак…

Недобитыши!
Первый недобитыш связан с навешиванием событий. Ну допустим, навесил ты событие на клик. А потом хочешь его убрать. Что будешь делать? Тут все зависит от того, как ты вешал событие. Если click(…) или bind(‘click’, …), то снять событие можешь unbind(‘click’). Если же пятно въелось сильнее событие повешено на live(‘click’, …), то тут без die(‘click’) не обойдешься. К слову, эти функции тебе пригодятся, когда начнешь писать свои плагины для jQuery, “не совместимые” с плагинами конкурентов. :twisted:
К слову, вешать bind’ом события можно не только стандартные, но и придуманные. А вызываться они будут trigger()’ом:

<br />
$(&#8216;p.hide&#8217;).bind(&#8216;oops&#8217;, function(){<br />
	this.style.display = &#8216;none&#8217;;<br />
}).children(&#8216;span.toggler&#8217;).click(function(){<br />
	$(this).parent().trigger(&#8216;oops&#8217;);<br />
});<br />

Далее, все функции прохода по DOM-дереву могут принимать css-селектор в качестве параметра. Это что-то типа фильтрации результатов выборки:

<br />
$(&#8216;a&#8217;).next(&#8216;span.red&#8217;).hide(); // прячем все span.red, идущие после a<br />
$(&#8216;a&#8217;).next().filter(&#8216;span.red&#8217;).hide(); // те же яйца, только в профиль<br />

К слову, не сказал про функцию closest(). Она принимает css-селектор и ищет первый элемент, подходящий под селектор, вверх по DOM-дереву.
<br />
$(&#8216;a.moar&#8217;).closest(&#8216;div.message&#8217;); // выбираем первого родителя a.moar, подходящего под div.message<br />

Плюс, есть такие функции, как prevAll() и nextAll(), выбирающие все элементы этого же уровня до или после элемента. Плюс, есть функция andSelf(), добавляющая элемент в выборку jQuery. К чему это я? К трюку с функцией index(). Функция принимает в себя селектор и возвращает позицию элемента, соответствующего селектору в выборке. Спорим, ты не понял, о чем это я? Я тоже не понял, но объясню примером:
</p>
<ul id="fst">
<li>1 лампочка</li>
<li>2 лампочка</li>
<li>3 лампочка</li>
</ul>
<ul id="snd">
<li></li>
<li></li>
<li></li>
</ul>
<p><script type="text/javascript">
$('#fst li').toggle(function(){
	$('#snd li').eq($('#fst li').index(this)).css({'color': '#ff0'}).html(' ыыы, горит');
}, function(){
	$('#snd li').eq($('#fst li').index(this)).css({'color': '#880'}).html('ща погаснет');
}, function(){
	$('#snd li').eq($('#fst li').index(this)).css({'color': '#000'}).html('');
});
</script><br />

Разбор полетов. Видишь функцию toggle()? Так вот, это не та toggle, которая мигает, это другая. Эта функция принимает в себя любое количество функций и по клику по элементу исполняет их по цепочке. Да, вешается только на click, причем не через live(). И да, путает неимоверно. Если хочешь события при наведении, используй hover(), но она терпит только две функции. Возвращаемся к нашим баранам. В данном случае indexиспользуется так: берется выборка $(‘#fst li’) и смотрится, каким элементов по счету в ней является кликнутый элемент aka this. И это число используется для обращения к элементу из $(‘#snd li’). Вот такие пироги с котятами.
Так вот, index() иногда можно заменить на prevAll().length! Фишка в том, что второй вариант работает быстрее, но он не всегда подходит.

Работа по DOM’у. Ок. После такой пляски с кодом самое время покурить и понять, что еще можно делать с элементами, кроме заCSSивания.
Им можно навешивать атрибуты: attr(‘param’) вернет значение атрибута, attr(‘param’, ‘value’) установит его. data() сделает тоже самое, но атрибут не окажет воздействия на элемент, а будет просто висеть где-то в пространстве.

<br />
$(&#8216;a&#8217;).hover(function(){<br />
	$(this).data(&#8216;href&#8217;, $(this).attr(&#8216;href&#8217;)).attr(&#8216;href&#8217;, &#8216;#&#8217;);<br />
}, function(){<br />
	$(this).attr(&#8216;href&#8217;, $(this).data(&#8216;href&#8217;));<br />
}); // счастливой отладки, #%&amp;amp;amp;amp;amp;amp;amp;@!<br />

Что еще можно? Можно вставить что-то до (before(хтмл или элемент)) или после элемента (after(хтмл или элемент)). Можно также сам элемент “подвинуть” (insertBefore(что-то) или insertAfter(что-то)). Также можно элемент не двигать, а использовать его клон (с потомками): clone([bool, [bool]]). Если указать clone(true), элемент клонируется со всеми событиями на нем. Если указать clone(true, true), выйдет совсем трушный клон элемента, с событиями на потомках. Пример:

</p>
<ul class="cloner">
<li><span>Ишшо</span> <input type="text" value="" /></li>
</ul>
<p><script type="text/javascript">
$('ul.cloner span').click(function(){
	var li = $(this).closest('li');
	li.after(li.clone(true));
});
</script><br />

Гляди в оба: на динамически сгенерированные span событие не распространяется, так как оно вешается через click(). Но зато оно копируется clone(true).

Ок, на сейчас все. А на очереди event’ы, анимация и ajax. Да, и не забывай почитывать ТТХ: это тебе еще пригодится.

Бонус: динамическое меню.

</p>
<style type="text/css">
.dynmenu{border:1px #88b solid;font-size:12px;list-style-type:none;margin:0;padding:0;width:200px}
.dynmenu li{background:#ddf;padding:2px 10px;text-align:right}
.dynmenu li:hover{background:#eef}
.dynmenu li span{cursor:pointer}
.dynmenu li .name{float:left}
.dynmenu li .name input{border:1px #88b solid;font-size:12px;height:16px;padding:0;width:100px}
.dynmenu li .copy, .dynmenu li .delete, .dynmenu li .up, .dynmenu li .down{padding:0 3px}
.dynmenu li .copy{color:#0c0}
.dynmenu li .delete{color:#c00}
.dynmenu li .up{color:#00c}
.dynmenu li .down{color:#cc0}
</style>
<ul class="dynmenu">
<li>
		<span class="name">Menu elt.</span><br />
		<span class="copy" title="Copy">C</span><br />
		<span class="delete" title="Delete">D</span><br />
		<span class="up" title="Up">^</span><br />
		<span class="down" title="Down">V</span>
	</li>
</ul>
<p><script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.js"></script><br />
<script type="text/javascript">
$(function(){
	var dm = $('.dynmenu');
	dm.find('.name').live('click', function(){
		var t = $(this);
		if(!t.find('input').length){
			t.html('<input type="text" value="'+t.html()+'" />');
		}
	}).find('input').live('change keydown', function(e){
		if(e.type == 'change' || e.keyCode == 13){
			var t = $(this);
			t.parent().html(t.val());
		}
	});</p>
<p>	dm.find('.copy').live('click', function(){
		var t = $(this).closest('li');
		t.after(t.clone());
	});</p>
<p>	dm.find('.delete').live('click', function(){
		if($(this).closest('.dynmenu').find('.delete').length > 1){
			$(this).closest('li').remove();
		}
	});</p>
<p>	dm.find('.up').live('click', function(){
		var t = $(this).closest('li');
		if(t.prev().length){
			t.insertBefore(t.prev());
		}
	});</p>
<p>	dm.find('.down').live('click', function(){
		var t = $(this).closest('li');
		if(t.next().length){
			t.insertAfter(t.next());
		}
	});
});
</script><br />

    • Alangel
    • Декабрь 15th, 2011 12:32пп

    В шестом примере $(‘ul.cloner > span’) уберите >

    • Crate
    • Февраль 6th, 2012 11:12дп

    hi!!!

  1. Трэкбэков пока нет.

T_T O_O =| =D =/ =) =( ;) :twisted: :idea: :cool: :blush: :?: :!:
*