Функция jQuery().slideDown

.slideDown( [ duration ], [ callback ] )Returns: jQuery 

Функция служит для создания эффекта скольжения элементов

.slideDown( [ duration ], [ callback ] )
duration строка или число, определяющее длительность анимации. 
callback функция, вызываемая после завершения анимации.


Используя метод .slideDown(), можно изменять высоту элементов, создавая эффект скольжения. При этом нижние элементы страницы опускаются вниз, позволяя появляться новым элементам.

Параметр Duration задает скорость анимации в миллисекундах. Чем больше это значение, тем медленее анимация, а не наоборот. Строки  'fast' и 'slow'  задают длительность анимации — 200 или 600 миллисекунд соответственно. Если указать другие строковые значения или не задать параметр вообще, то по умолчанию используется интервал в 400 миллисекунд.

Параметр callback — это указатель на функцию, которая запускается после завершения анимации (необязательный параметр). Как правило, этот параметр используется, чтобы связать несколько разных анимаций. Важно помнить, что при создании анимации для нескольких элементов, функция callback выполняется для каждого элемента, а не для всей анимации в целом.

Пример:
<div id="clickme">
  Click here
</div>
<img id="book" src="book.png" alt="" width="100" height="123" />
With the element initially hidden, we can show it slowly:
$('#clickme').click(function() {
  $('#book').slideDown('slow', function() {
    // Animation complete.
  });
});

Функция jQuery().fadeIn

.fadeIn( [ duration ], [ callback ] )
Функция fadeIn() служит для создания эффекта проявляющихся элементов путем изменения параметра «opacity» с 0% до 100%.


.fadeIn( [ duration ], [ callback ] )
duration - строка или число, определяющее длительность анимации.
callback - функция, к которой обращается программа, как только анимация закончится.  


Параметр «duration» задает скорость анимации в миллисекундах. Если вместо числа указать значение «fast» или «slow», то длительность анимации будет соответствовать интервалам 200 и 600 миллисекунд. Если указать другие строковые значения или не задать параметр вообще, то по умолчанию используется интервал в 400 миллисекунд.

Параметр Callback — это указатель на функцию, которая запускается после завершения анимации (необязательный параметр). Как правило, это свойство используется, чтобы связать несколько разных анимаций.
Сделать анимацию можно для любого элемента, например, для простого изображения:

<div id="clickme">
      Click here
    </div>
    <img id="book" src="book.png" alt="" width="100" height="123" />
    With the element initially hidden, we can show it slowly:
    $('#clickme').click(function() {
      $('#book').fadeIn('slow', function() {
        // Animation complete
      });
    });

Функция jQuery().hide

jQuery().hide() служит для того, чтобы скрывать выбранные по селектору элементы. Синтаксис данной функции следующий:


.hide(duration, [callback])
  duration - это числовой или строковый параметр, 
             определяющий с какой скоростью скрывать элементы
  callback - (необязательный параметр) функция которая 
             вызывается после завершения анимации


В случае вызова hide() без параметров, элементы будут скрыты немедленно. По сути, данный вариант аналогичен вызову .css('display', 'none') за тем исключением, что в случае с .css значение параметра 'display' будет сохранено в кэше jQuery и в последствии может быть от туда извлечено.

Если же в функцию hide() передать параметр duration, то функция работает как метод animate() последовательно уменьшая высоту, ширину и прозрачность элементов.

Параметр duration может принимать одно из двух строковых значений — 'slow' или 'fast', либо произвольное целое значение. По умолчанию, в jQuery значению 'slow' сопоставлена задержка в 600мс, а 'fast' в 200мс.

Для наглядности небольшой пример:


<!DOCTYPE html>
<html>
<head>
  <script src="/jquery.js"></script>
</head>
<body>
  <p>Привет</p>
  <a href="#">Щелкни по ссылке, чтобы закрыть и ее</a>
  <p>Еще один параграф</p>
<script>

    $("p").hide();
    $("a").click(function () {
      $(this).hide();
      return true;
    });
</script>
</body>
</html>

Функция jQuery.each

jQuery.each() — это итератор, т.е. такая функция которая перебирает все элементы массива или объекта. Синтаксис данной функции имеет следующий вид:


jQuery.each(collection, callback(indexInArray, valueOfElement) )

  collection - массив или объект
  callback - функция которая будет вызываться для каждого элемента коллекции


Внимание! Не нужно путать функцию jQuery.each() с функцией $(selector).each() — в первом случае функция each работает с произвольной коллекцией, которая передается ей в качестве первого аргумента, а во втором только с элементами jQuery, которые были выбраны в рамках используемого селектора.

Более того, если посмотреть код jQuery, то легко убедиться, что функция $(selector).each() — это не что иное как обертка для функции jQuery.each(), где в качестве первого аргумента передается элемент this:


	// Execute a callback for every element in the matched set.
	// (You can seed the arguments with an array of args, but this is
	// only used internally.)
	each: function( callback, args ) {
		return jQuery.each( this, callback, args );
	}



Возможно, кому-то покажется странным, что в качестве коллекции передается указать this. Хотя на самом деле ничего странного здесь нет, достаточно вспомнить, что экземпляр класса jQuery — это ни что иное как коллекция dom-элементов, которые были выбраны на основании заданного селектора.

Иногда, в процессе перебора элементов коллекции, возникает необходимость прекратить дальнейший перебор. Для этого достаточно в callback-е (см. синтаксис jQuery.each() использовать конструкцию "return false;".

Другими словами функция-обработчик возвращающая булево значение «false» останавливает дальнейший перебор элементов коллекции.

Для наглядности приведу пару примеров:


$.each([111, 43, 43], function(index, value) { 
  alert(index + ': ' + value); 
});

Результат:
0:111
1:43
2:43



var map = { 
  'flammable': 'inflammable', 
  'duh': 'no duh' 
}; 
$.each(map, function(key, value) { 
  alert(key + ': ' + value); 
});

Результат:
flammable: inflammable
duh: no duh 


Если после прочтения заметки появились какие-то мысли, замечания или просто желание сказать спасибо, то милости прошу в комментарии.

Работа с checkbox в jQuery

Решение для нетерпеливых:

<script>
$("input:checkbox").attr("checked","checked"); // устанавливает галочку на все checkbox-ы
$("input:checkbox").removeAttr("checked"); // снимает галочку со всех checkbox-ов
</script>


Далее обо всем по порядку.

Еще раз о селекторах

В первую очередь, при работе с checkbox-ами в jQuery нужно составить правильный селектор. Селектор — это выражение по которому jQuery выбирает необходимые dom-элементы для обработки.
Если селектор будет составлен неправильно, то это приведет к тому, что jQuery захватит не те элементы. В результате на странице может получиться полная каша.

Составляем правильный селектор

Для того, чтобы построить правильный селектор нужно внимательно посмотреть на HTML код с помощью которого создаются элементы checkbox:


<input type="checkbox" value="" name="chbx"/>


Из приведенного кода видно, что как таковой checkbox это элемент input со специальным типом "checkbox".

Так как отдельного элемента «checkbox» не существует, то использование jQuery селектора "$('.checkbox')" бессмысленно — на странице попросту нет таких элементов. Использование другого селектора — "$('.input')", так же не дает положительного результата, потому что на странице может быть множество input-ов с различными типами — кнопки, checkbox-ы, скрытые элементы, файлы и т.д.

Поэтому, правильным будет следующий селектор "$('input[type=checkbox]')", или более сокращенный его вариант "$('[type=checkbox]')". В последнем случае мы опустили слово «input», а это значит, что поиск checkbox-ов будет идти по всем элементам присутствующим на странице (слои, ссылки, параграфы и т.д.), что, конечно, негативно скажется на скорости работы jQuery.

Кроме предложенного варианта существует еще один селектор, который так же находит все checkbox-ы: "$('input:checkbox')" или "$(':checkbox')". Опять же обращаю внимание, что во втором случае поиск будет идти по всем элементам страницы, т.е. фактически по селектору "$('*:checkbox')".

Как отметить все элементы checkbox на странице

Имея правильны селектор, теперь можно перейти к тому как jQuery позволяет обработать необходимые элементы. Например, очень часто нужно отметить все элементы checkbox на странцие. Для этого на checkbox нужно добавить атрибут «checked».

Добавление атрибутов на элементы в jQuery делается с помощью специального метода "attr", а удаление с помощью метода "removeAttr". Работу с этими методами демонстрирует следующий пример:


<!DOCTYPE html>
<html>
<head>
  <style>
  textarea { height:25px; }
  </style>
  <script src="/js/jquery.js"></script>
</head>
<body>
	<form>
    <input type="button" value="Элемент Input c типом 'Button'"/>
    <input type="checkbox" />

    <input type="checkbox" />
    <input type="file" />
    <input type="hidden" />

    <input type="image" />
    <input type="password" />
    <input type="radio" />

    <input type="reset" />
    <input type="submit" />
    <input type="text" />

    <select><option>Option<option/></select>
    <textarea></textarea>
    <button>Button</button>
  </form>

  <div>
  </div>
<script>
$("input:checkbox").attr("checked","checked"); // устанавливает галочку на все checkbox-ы
$("input:checkbox").removeAttr("checked"); // снимает галочку со всех checkbox-ов
</script>
</body>
</html>


На этом хотелось бы закончить, но если появились вопросы или дополнения к статье прошу оставлять их в комментариях.

Функцция jQuery.live

Начиная с версии 1.3 в jQuery появилась функция live, которая является аналогом функции bind и так же служит для назначения событий всем элементам, которые соответствуют выражению заданному в селекторе jQuery.

Основное отличие функции jQuery.live от jQuery.bind состоит в том, что bind действует только на объекты, которые существовали на момент вызова функции. Для объектов созданных позднее необходимо запускать bind повторно.

Функция jQuery.live лишена этого недостатка и будучи запущена один раз позволяет назначить события не только на созданные объекты, но и на те объекты, которые появятся позже.

Для иллюстрации сказанного, приведу небольшой пример:


<body>
	<div class=clickme>
	  Click Here
	</div>


Для того, чтобы «оживить» данный пример добавим обработку события «click»:


$('.clickme').bind('click', function() {
// Обработчик события Click
});


Недостаток в том, что после того как будет добавлен дополнительный элемент, с тем же классом «clickme», созданный с помощью bind обработчик событий для него действовать не будет.


$('body').append('<div class=clickme>Click here too</div>'); 


Кому-то данное ограничение может показаться незначительным, но на самом деле это большая проблема. Ведь, для каждого нового элемента необходимо повторно назначать события, а это выливается в увеличение объема и сложности программы.

Появление новой функции jQuery.live значительно упрощает жизнь программиста и позволяет уменьшить сложность программы, а следовательно и риск ошибки.

Синтаксис функции аналогичен синтаксису команды bind:


.live(eventType, handler);


Поэтому единственное отличие между приведенным выше кодом для bind и кодом для live заключается в замене имени одной функции на другое:


$('.clickme').live('click', function() {
// Обработчик события Click
});


В дополнение хочу отметить, что начиная с версии jQuery 1.4.1 прототип функции live стал выглядеть иначе:

.live( eventType, eventData, handler )


EventData — это необязательный параметр, который предназначен для передачи в обработчик дополнительных данных.
Одновременно с этим изменением появилась возможность назначать несколько событий на один обработчик:


$('.clickme').live('mouseover mouseout', function() {
	if (event.type=='mouseover') {
		// обрабатываем mouseover
	}

	if (event.type=='mouseout') {
		// обрабатываем mouseout
	}

});


Думаю, что многие оценят полезность функции live и постепенно начнут переписывать свои программы на новый лад. Что касается меня, то процесс перехода уже начат.

Для чего нужен jQuery.fn

Каждый кто сталкивался с написанием собственных плагинов на jQuery задавал вопрос — "В чем различие между объявлением функций через jQuery и jQuery.fn?".

Для того, чтобы ответить на поставленный вопрос приведу два примера.

Пример 1.

jQuery.sayHello = function() {
  alert('Привет! Найдено ' + this.length + 'элементов' );
}

$('div').sayHello(); // ничего не происходит


Пример 2.

jQuery.fn.sayHello = function() {
  alert('Привет! Найдено ' + this.length + 'элементов' );
}

$('div').sayHello(); // Выводит "Привет! найдено ХХ элементов", где ХХ - это количество найденных элементов на странице


Если запустить первый пример, то произойдет одно из двух событий — браузер выдаст ошибку (например, если у Вас установлен FireBug) либо не выдаст ничего. А если запустить второй пример, то на экране появится сообщение о количестве найденных элементов.

Прежде чем делать какие-либо выводы, приведу еще один пример:


jQuery.sayHello = function(elem) {
  alert('Привет! Найдено ' + elem.length + 'элементов' );
}

jQuery.sayHello($('div'));


В данном примере, будет выдано сообщение о количестве найденных объектов.

Думаю теперь у нас достаточно информации, чтобы сделать некоторые выводы:

Вывод 1: Если задать функцию через jQuery.fn, то она будет работать с элементами найденными через функцию $(). Контекст этой функции будет содержать выбранные элементы;

Вывод 2: Если задать функцию через jQuery, то к ней можно обратиться только через глобальный объект jQuery. В таком случае контекст функции будет указывать на глобальный объект window.

Таким образом, если нужно написать плагин, который будет работать только с выбранными объектами, то нужно его создавать в jQuery.fn, а если нам неважно какие элементы страницы были выбраны, то лучше создавать функцию через jQuery.

Как быстро проверить число на NaN

Сегодня копался в коде jQuery и обратил внимание на то каким образом осуществляется проверка числа на NaN. Вместо того, чтобы использовать стандартную функцию isNaN() Johng Resig преобразует число к строке и сравнивает его со строкой 'NaN'.

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


Для проверки я написал простенький скрипт:


function a() {
	for (var i = 0; i < 100000; i++) {
		var n = parseInt('AAAA');
		isNaN(n); // true
	}
}

function b() {
	for (var i = 0; i < 100000; i++) {
		var n = parseInt('AAAA');
		'NaN' == n.toString() ; // true
	}
}

a();
b();


Чтобы не заморачиваться на измерение скорости средствами JavaScript использовал профилирование встроенное в плагин FireBug.

После проведение замеров FireBug показал следующее:
функция b() — 32 мс
функция a() -13 мс.


Получается, что isNaN работает быстрее более чем в два раза!

Ради справедливости стоит отметить, что в других браузерах результаты могут быть иными, возможно даже в более старой версии FireFox-а выигрыш будет на стороне toString(). Но в FireFox 3.6 ситуация такая как я описал выше.

Если кто-то может привести данные о времени работы аналогичного кода для Оперы и IE милости прошу отписаться в комментариях.

Из сказанного выше, можно сделать вывод, что для работы в FireFox лучше использовать функцию isNaN. Но значит ли, что не существует другого более быстрого способа проверить число на NaN?

Чтобы ответить на данный вопрос, я решил провести еще пару экспериментов.

Первое, что пришло мне на ум — это изменить способ перевода числа в строку, для этого я заменил код n.toString() == 'NaN' на n + '' === 'NaN'; в результате функция b(); стала выполняться на 5мс быстрее. Но функция isNaN() все равно работала значительно лучше.

Второе решение, я нашел в интернете и заключается оно в том, чтобы проверить равно ли число само себе, а точнее не равно ли оно само себе:

var n = parseInt('AAAA');
n != n // true 


Я уже писал об особенностях числа NaN одно из которых заключается в том, что NaN не равно самому себе, таким образом сравнение n != n будет истинным только в случае когда n равно NaN.

Чтобы проверить указанный метод. Я заменил проверку toString() на n != n и запустил профилирование повторно. В результате были получены следующие значения:

функция a() — 13 мс
функция b() — 8 мс (!)


Таким образом, на сегодняшний день самый быстрый способ (известный мне) проверить число на значение NaN — это выполнить проверку n != n.

JavaScript. Грабли с NaN

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

Например, в JS есть такое значение — NaN расшифровывается как Not A Number. Обычно это значение возвращается при ошибке выполнения операций с числами.


parseInt('AAAA'); // NaN
parseInt('1'); // 1
parseInt('16 somthing else'); // 16 — неожиданно, правда?


В данном примере, при выполнении первой операции функция parseInt не смогла преобразовать строку в число и поэтому вернула значения NaN. А вот в 3-ей строке, все прошло успешно, что кажется мне не совсем логичным.

Другие фокусы, которые выкидывает JavaScript хорошо демонстрирует следующий пример:


NaN == NaN; // false
NaN != NaN; // true
NaN > NaN; // false
NaN < NaN; // false

typeof NaN === 'number';  // true


Получается, что NaN не равен сам себе, одновременно NaN не больше и не меньше самого себя. А если запросить его тип, то оказывается, что это число. Непонятно, почему тогда не работают операции сравнения.

Плохо в данной ситуации то, что код который многим кажется вполне рабочим, на самом деле таковым не является:



function sum(a, b) {
	a = parseInt(a, 10);
	b = parseInt(b, 10);
	if (a == NaN || b == NaN) {
		alert('Ошибка');
		return 0; 
	}
	return a+b;
}

sum('1', 'bbbb');  // NaN



Причина, в том, что сравнение a == NaN || b == NaN — всегда будет возвращать false, даже если a или b будут иметь значение NaN.

Для того, чтобы узнать содержит ли переменная значение NaN используется функция isNaN:


isNaN(NaN); // true
isNaN('AAAA'); // true
isNaN('0'); // false


Чтобы избежать проблем со значением NaN я использую собственную функцию определения является ли переменная числом:


function isNum(v) {
	return typeof v === 'number' && isFinite(v);
}
  • 0
  • 28 января 2010, 06:04
  • admin
  • 1+1

Подводные камни JavaScript или опасное свойство Semicolon insertion.

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

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


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

var a
var b

Во время выполнения он будет преобразован к следующем виду:

var a;
var b;


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

Для примера возьмем следующий код:

function a() {
return 
	false;
}

Не трудно догадаться, что в данной ситуации программист хотел чтобы функция возвращала значение «false». Но на самом деле она возвращает значение «undefined». И это вполне закономерно, потому что реально исполняется совсем другой код:

function a() {
return ; // Обратите внимание JS сам доставил «недостающий» знак точки с запятой
	false;
}

Самое простое, что можно сделать для избежания проблем с Semicolon insertion — это не разрывать строки на две подстроки. Но и этого будет недостаточно, для написания абсолютно безопасного кода.

Синтаксис JavaScript очень похож на синтаксис языка «Си». Например, для выделения блоков когда в JS как и в «Си» используются фигурные скобки.

Обычно программисты предпочитают один из двух вариантов оформления.

Первый — это когда открывающая фигурная скобка находится на одном уровне с конструкцией к конторой она относится:
function a() {
	return {
		value: false
	}
}

Второй — когда открывающую скобку помещают на уровень ниже

function a() 
{
	return 
	{
		value: false
	}
}

Не трудно догадаться, что для JavaScript второй вариант пригоден не во всех случаях, в примере выше во время выполнения будет получен следующий код:

function a() 
{
	return ;
	value: 
		false;
}

Обратите внимание, что в этом примере не только прибавились «недостающие» знаки, но и исчезли «лишние» символы фигурных скобок. Поэтому, чтобы избежать проблем в JavaScript, лучше не использовать переносы строк перед открывающей фигурной скобкой.

Конечно, сказанное выше описывает далеко не все возможные ситуации когда Semicolon insertion вызовет проблемы при выполнении кода. Поэтому я приглашаю всех дополнить эту статью своими примерами и мыслями используя для этого комментарии.
  • 0
  • 25 января 2010, 07:19
  • admin
  • 1+1
Продвижение сайтов