Использование jQuery delay () с отдельными элементами - PullRequest
2 голосов
/ 02 марта 2010

Я хочу подделать простую анимацию при загрузке страницы, последовательно открывая несколько png-файлов, каждый из которых появляется мгновенно, но с уникальной, точно синхронизированной задержкой перед следующей. Использование последней версии jQuery (1.4.2 на момент написания), которая предоставляет метод задержки. Мой первый (мозговой покой) импульс был:

$('#image1').show('fast').delay(800);
$('#image2').show('fast').delay(1200);
$('#image3').show('fast');

Конечно, все приходят одновременно. Примеры документов jQuery относятся к одному элементу, который не связан с несколькими элементами. ОК ... попробуйте еще раз, используя вложенные обратные вызовы из show ():

$('#image1').show('fast', function() {
    $('#image2').show('fast', function() {      
        $('#image3').show('fast', function() {      
        });
    });
});

Выглядит некрасиво (представьте, что вы делаете 10, а также удивляетесь, каким будет попадание процессора), но эй, это работает последовательно! Без задержек, хотя. Итак ... цепочка задержки () после show () с использованием функции обратного вызова из нее (даже не уверена, поддерживает ли она одну):

$('#image1').show('fast').delay(800, function() {
    $('#image2').show('fast').delay(1200, function() {      
        $('#image3').show('fast');
    });
});

Hm. Противоположный результат того, что я думал, может произойти: обратный вызов работает, но все равно без задержки. Итак ... я должен использовать некоторую комбинацию очереди и задержки вместо вложенных обратных вызовов? Примеры документов jQuery для очереди снова используют только один элемент, например. Предположение об этом потребует использования пользовательской очереди, но я не знаю, как это реализовать. Или может я упускаю простой способ? (Для простой проблемы!)

Ответы [ 5 ]

3 голосов
/ 02 марта 2010

Вы могли бы упростить это, если бы они были там вместе:

function showNext(img) {
  //show, find next image, repeat, when next doesn't find anything, it'll stop
  img.show('fast', function() { showNext($(this).next('[id^=image]')); });
}
//Call the first image to start the chain
showNext($("#image1"));

Если они находятся дальше друг от друга, просто настройте этот селектор .next() на то, как найти следующее изображение, или вы можете назначить им класс и т. Д., Однако вы можете перейти к следующему действующему. *

2 голосов
/ 02 марта 2010

Дикая догадка здесь, но как насчет

$('#image1').show('fast', function() {
    $('#image2').delay(800).show('fast', function() {      
        $('#image3').delay(1200).show('fast', function() {      
        });
    });
});
0 голосов
/ 26 октября 2013

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

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

$('#image1').delay(800).show('fast');

Это будет ждать 0,8 секунды, а затем быстро показывать изображение (длительность «быстро» = 0,2 секунды).

Во-вторых, если у вас есть несколько действий, которые вы хотите запустить одновременно , вы просто пишете их одно за другим :

$('#image1').show('fast');
$('#image2').show('fast');

Таким образом, они все начнутся в одно и то же время , поэтому приведенный выше код будет воспроизводить постепенную анимацию # image1 и # image2 параллельно!

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

$('#image1').show('slow');
$('#image2').delay(1000).show('slow');
$('#image3').delay(1600).show('slow');
$('#image4').delay(2000).show('slow');

В зависимости от задержек и продолжительности, это позволяет воспроизводить анимации с промежутками между ними (2 начинается с задержкой после окончания 1), последовательно (3 запускается, когда 2 только что закончились, длительность «медленная»). составляет 600 мс) и задерживается, но с перекрытием (4 запуска, в то время как 3 все еще работает). Все, что вам нужно сделать, это адаптировать ваши задержки и продолжительность. На самом деле это ответ на ваш вопрос и самый универсальный способ сделать то, что вы хотите.

Слово о функции обратного вызова : доступно с show (), animate () и некоторыми другими методами (но не с задержкой, как вы пытались!) И в основном необходимо, если вы хотите делать более сложные вещи после завершения анимации. Будьте осторожны: когда ваш селектор соответствует нескольким элементам, например, $('#image1, #image2'), обратный вызов будет вызываться несколько (!) Раз - по одному разу для каждого элемента в вашем наборе. Это может привести к очень неожиданным результатам (быстрый совет: во избежание этого ищите информацию о методах jQuery when () / then ()).

Наконец, ради полноты, если вы просто хотите запустить несколько анимаций на одинаковых элементах (элементах) - одна анимация за другой и с возможными задержками между - вы можете просто сделать ...

$('#image1').show('fast').hide('slow').delay(500).show('slow').hide('fast');

Это быстро покажет изображение, затем медленно скроет его, затем подождет полсекунды, затем покажет медленно и затем скроет быстро.

0 голосов
/ 30 апреля 2010

Использование очереди довольно просто:

var imgs = ['#image1','#image2','#image3',...];

function showNext() {
  var img = imgs.shift();
  if (img) $(img).show('fast', showNext);  
}

showNext(); // start
0 голосов
/ 02 марта 2010

Вероятно, есть модный способ сделать это напрямую с помощью jQuery, но я бы соблазнился сделать это с помощью простого массива и простого механизма тайм-аута.

var toShow = ["image1", "image2", "image3", ... ], index = 0;
setTimeout(function() {
  $('#' + toShow[index++]).show('fast');
  if (index >= toShow.length) return;
  setTimeout(arguments.callee, 1000);
}, 1000);

Вы также можете поместить значения «задержки» в массив, если они не должны быть одинаковыми все время:

var toShow = [ {img: "image1", delay: 800}, {img: "image2", delay: 1200}, ... ],
  index = 0;
setTimeout(function() {
  $('#' + toShow[index].img).show('fast');
  if (index >= toShow.length) return;
  setTimeout(arguments.callee, toShow[index].delay);
}, toShow[0].delay);

edit это весело :-) Если вы хотите, вы можете построить массив изображений как объект jQuery & mdash; другими словами, вы можете поместить изображения в HTML, а затем «найти» их с помощью селектора jQuery. Что касается значений задержки, хорошо, если вы хотите сделать задержку индивидуальной для каждого изображения, вы можете кодировать это в имя класса изображения либо с помощью плагина jQuery «метаданные», либо с более простым взломом, если вам не нужно разработать для других вещей:

var toShow = $('img.showMeSlowly'), index = 0, getDelay = function(img) {
  var delay = 1000;
  $(img).attr('class').replace(/.*\bdelay:(\d+)\b.*/, function(_, ds) {
    delay = parseInt(ds, 10);
  });
  return delay;
};

setTimeout(function() {
  toShow.eq(index++).show('fast');
  if (index >= toShow.length) return;
  setTimeout(arguments.callee, getDelay(toShow.get(index)));
}, getDelay(toShow.get(0)));
...