JavaScript. Последовательное выполнение действий

Published: 11.11.2011

Так, с чего начать... Да чего уж там, начну с самого главного — с постановки задачи. Итак есть у нас несколько элементов, пусть будет три.

==1==
==2==
==3==

 

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

Начал с главного, продолжу вступлением. В этой статье я использую javascript-библиотеку jQuery, возможно, есть UI-плагин к jQuery, который исходную задачу может решить одной строчкой кода (не считая 100500 строчек кода самого плагина, хе). Я же делаю акцент на сам механизм последовательного выполнения действий, который можно применять и в чистом JavaScript.

Итак, допустим, у нас есть 3 элемента. Представим, что они пришли извне, например, при помощи аякса, и мы их на лету записываем в объект jQuery:

var elements = $("<div id='e0'>==1==</div><div id='e1'>==2==</div><div id='e2'>==3==</div>");
Пример 0. Вывод одного элемента

С медленным появлением проблем нет, jQuery это умеет. Элемент <div id="demo_area"> - место, куда мы выводим наши элементы. Вот так выводим один элемент (в стилях CSS наши элементы предварительно скрыты display: none), который в течение полутора секунд становится непрозрачным:

$(elements).filter('#e0').appendTo('#demo_area').fadeIn(1500);

Смотрим: Пример 0

Кстати, однажды открыв демонстрационную страницу можно больше не нажимать на ссылки с примерами здесь, а на странице с примерами нажимать на соответствующие кнопки.

Пример 1. Первый блин комом

Всем же очевидно, как вывести 3 элемента? Что? Просто загнать вывод элементов в цикл? Ну, что ж, давайте попробуем:

$(elements).each(function() {
  $(this).appendTo('#demo_area').fadeIn(1500);
});

Как видим, Пример 1, не получилось. Каждый элемент получил собственный метод fadeIn, которые выполняются одновременно и независимо друг от друга. Пичалька.

Пример 2. Ого, оно ещё и работает

А, значит, если кто ещё не знает, самое время использовать JavaScript метод setInterval. Пробуем.

  1. var count = $(elements).length; // количество элементов
  2. var i = 0; // счётчик
  3. var interval = setInterval(function() { // записываем идентификатор интервала в переменную
  4.       $(elements).filter('#e' + i++).appendTo('#demo_area').fadeIn(1500); // выводим элемент, увеличиваем счётчик
  5.       if (i == count) { // выход из цикла
  6.         clearInterval(interval);
  7.       }
  8.     }, 1500); // интервал = 1,5 секунды

Ура! Работает! Пример 2.

Пример 3. Работа над ошибками

Есть, правда, в предыдущем примере некоторые недостатки. Элементы отображаются через заданный интервал времени, однако, и перед отображением первого элемента тоже выполняется интервал. Логичнее было бы, если первый элемент начинал выводиться на экран сразу же, а остальные через интервал. И сам интервал сделаем поменьше, что даст более «плавное» отображение элементов. После небольшой модификации кода получим:

  1. var count = $(elements).length;
  2. var i = 0;
  3.  
  4. // выносим первый элемент за интервал для мгновенного выполнения
  5. $(elements).filter('#e' + i++).appendTo('#demo_area').fadeIn(1500);
  6.  
  7. var intervalId = setInterval(function() {
  8.       $(elements).filter('#e' + i++).appendTo('#demo_area').fadeIn(1500);
  9.       if (i == count) {
  10.         clearInterval(intervalId);
  11.       }
  12.     }, 500);

Так-то получше будет. Пример 3.

Пример 4. Для месье, знающих толк в извращениях

Предыдущий пример, выполненный через setTimeout

  1. var count = $(elements).length;
  2. var i = 0;
  3. (function(){
  4.   $(elements).filter('#e' + i++).appendTo('#demo_area').fadeIn(1500);
  5.   if (i < count) { setTimeout(arguments.callee, 500); }
  6.   else { return ; }
  7. })();

Смотрим результат: Пример 4

Скачать архив с исходниками