2010-03-02 6 views
2

Je veux simuler une animation simple sur le chargement de la page en révélant séquentiellement plusieurs png, chacun apparaissant instantanément mais avec un délai unique et précis avant le prochain. En utilisant la dernière version de jQuery (1.4.2 à l'écriture), qui fournit une méthode de délai. Ma première impulsion (braindead) était:Utilisation de jQuery delay() avec des éléments séparés

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

Bien sûr, tous viennent simultanément. Les exemples de documentation jQuery se réfèrent à un seul élément en cours de chaînage, ne gérant pas plusieurs éléments. OK ... essayez à nouveau en utilisant callbacks imbriqués de show():

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

est moche (imaginez faire 10, me demande aussi ce succès processeur serait) mais bon, il fonctionne de façon séquentielle! Sans délai cependant. Alors ... retard de la chaîne() après exposition() en utilisant une fonction de rappel de celui-ci (même pas sûr si elle prend en charge un):

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

Hm. Résultat opposé de ce que je pensais pouvoir arriver: le rappel fonctionne, mais toujours pas de retard. Alors ... devrais-je utiliser une combinaison de file d'attente et de délai au lieu de rappels imbriqués? Les exemples de documentation jQuery pour la file d'attente n'utilisent à nouveau qu'un seul élément par exemple. Deviner cela impliquerait l'utilisation d'une file d'attente personnalisée, mais je ne sais pas comment l'implémenter. Ou peut-être que je manque un moyen simple? (Pour un simple problème!)

Répondre

2

conjecture sauvage ici, mais qu'en est-

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

Votre conjecture sauvage fonctionne bien! Et la syntaxe me semble maintenant évident . (En attendant d'autres solutions qui pourraient éviter l'imbrication avant de cocher, nous reviendrons plus tard aujourd'hui.) Merci! – boomturn

0

Il y a probablement une manière à la mode de le faire directement avec jQuery mais je serais tenté de le faire avec un simple tableau et un mécanisme de délai d'attente simple.

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

Vous pouvez mettre vos valeurs « retard » dans le tableau aussi, si elles ne sont pas censés être le même tout le temps:

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); 

modifier ce est amusant :-) Si vous le souhaitez, vous pouvez créer le tableau d'images en tant qu'objet jQuery — en d'autres termes, vous pouvez déposer les images dans votre code HTML, puis les "rechercher" avec un sélecteur jQuery. En ce qui concerne les valeurs de délai, si vous voulez faire du retard une chose par image, vous pouvez le coder dans le nom de la classe image soit avec le plugin jQuery "metadata" soit avec un hack plus simple si vous n'avez besoin de rien élaboré pour d'autres choses:

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))); 
+0

Merci pour cela. Je pense que l'affiche ci-dessous a donné ce que je cherchais (je suis à l'extrémité peu profonde de la piscine!). C'est plus que ce à quoi je m'attendais, je l'examinerai plus tard. – boomturn

3

Vous pouvez simplifier si elles sont là ensemble:

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")); 

Si elles sont plus, réglez juste que .next() sélecteur sur la façon de trouver l'image suivante, ou vous pouvez leur assigner une classe, etc ... mais vous pouvez passer à la suivante.

0

En utilisant une file d'attente est assez simple:

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

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

showNext(); // start 
0

Je suis un peu étonné au sujet des réponses données weired ici. La question est un peu plus ancienne, mais je suppose que d'autres vont encore chercher et trouver ceci, alors allons-y:

Tout d'abord, delay() n'accepte pas une fonction de rappel.Si vous voulez retarder toute action, vous devez mettre le retard() dans la chaîne de points notation devant de l'action:

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

Cela attendra pendant 0,8 seconde puis révéler l'image rapidement (durée 'rapide' = 0,2 seconde).

Deuxièmement, si vous avez plusieurs actions que vous souhaitez exécuter simultanément, vous écrivez simplement un après l'autre:

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

De cette façon, ils seront tous commencer en même temps , donc le code ci-dessus jouera l'animation de fondu de # image1 et # image2 en parallèle!

Si vous souhaitez démarrer plusieurs animations avec des retards différents, vous combinez les deux stratégies et simplement faire:

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

Selon les retards et les durées, ce qui vous permet de jouer les animations avec des écarts entre-deux chaque (2 commence avec un délai après que 1 soit fini), consécutivement (3 commence quand 2 vient de finir, car la durée 'lente' est de 600 ms) et retardé mais avec chevauchement (4 départs alors que 3 est toujours en cours). Tout ce que vous avez à faire est d'adapter vos retards et vos durées. C'est en fait la réponse à votre question et la méthode la plus polyvalente pour faire ce que vous voulez. Un mot sur la fonction de rappel : Ceci est disponible avec show(), animate() et plusieurs autres méthodes (mais pas avec delay, comme vous l'avez essayé!) Et est principalement nécessaire si vous voulez en faire plus choses complexes après une animation est terminée. Faites attention cependant: lorsque votre sélecteur correspond à plusieurs éléments, par ex. $('#image1, #image2'), le rappel sera appelé multiple (!) Fois - une fois pour chaque élément de votre ensemble. Cela peut conduire à des résultats très inattendus (indice rapide: recherchez des informations sur les méthodes when()/then() de jQuery pour éviter cela).

Enfin et dans un souci d'exhaustivité, si vous voulez simplement exécuter multiples animations sur le même élément (s) - une animation après l'autre et avec des retards possibles entre-deux - vous pouvez simplement faire. ..

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

Cela montrera l'image rapidement, puis le cacher lentement, puis attendre une demi-seconde, puis le montrer lentement puis cacher rapidement.