2009-05-05 10 views
3

J'ai mis en place une animation pour mon blog photo. J'ai toujours un gros problème car l'élément 'body' active l'animation deux fois.jQuery: L'élément 'body' active deux fois l'événement scroll

Je pense que le problème vient du $ ('body'). Animate. Parce que je pense que lorsque le corps s'anime, l'événement de défilement serait à nouveau activé et déclencherait donc l'événement deux fois.

Le problème de mon code est de faire défiler la page vers le haut. Quand je fais défiler la page vers le haut. Le scrollAnimatePrev se déclenche et l'élément $ ('body') s'anime. Après l'animation, la variable d'animation est définie sur false. Mais l'élément $ ('body') déclenche l'événement scroll car je suppose que lorsque je définis le scrollTop, l'événement scroll est déclenché. Donc encore une fois, currentPos est mis à $ (window) .scrollTop() alors currentPos> previousPos renvoie true et! Animating renvoie true pour déclencher le scrollAnimate.

Maintenant, je veux résoudre ce problème. Comment?

$(function() { 
     var record = 0; 
     var imgHeight = $(".images").height(); 
     var offset = $(".images").eq(0).offset(); 
     var offsetHeight = offset.top; 
     var previousPos = $(window).scrollTop(); 
     var animating = false; 
     var state = 0; 
     $(window).scroll(function() { 
      var currentPos = $(window).scrollTop(); 
      console.log(currentPos); 
      if(currentPos > previousPos && !animating) { 
       record++; 
       scrollAnimate(record, imgHeight, offsetHeight); 
       animating = true; 
      } else if (currentPos < previousPos && !animating) { 
       record-- 
       scrollAnimatePrev(record, imgHeight, offsetHeight); 
       animating = true; 
      } 
      previousPos = currentPos; 
      console.log(previousPos) 
     }) 


     function scrollAnimate(record, imgHeight, offsetHeight) { 
      $('body').animate(
       {scrollTop: (parseInt(offsetHeight) * (record+1)) + (parseInt(imgHeight) * record)}, 
       1000, 
       "easeInOutQuart"      
      ) 
      .animate(
       {scrollTop: (parseInt(offsetHeight) * (record)) + (parseInt(imgHeight) * (record))}, 
       1000, 
       "easeOutBounce", 
       function() { 
        animating = false; 
       } 
      ) 
     } 

     function scrollAnimatePrev(record, imgHeight, offsetHeight) { 
      $('body').animate(
       {scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record)) - offsetHeight}, 
       1000, 
       "easeInOutQuart" 
      ) 
      .animate(
       {scrollTop: ((parseInt(imgHeight) * record) + (parseInt(offsetHeight) * record))}, 
       1000, 
       "easeOutBounce", 
       function() { 
        animating = false; 
       } 
      ) 
     } 
    }) 

Répondre

3

Je pense que cela pourrait déclencher deux fois le rappel. J'ai eu un problème similaire récemment.

j'avais quelque chose similaire à

$('#id, #id2').animate({width: '200px'}, 100, function() { doSomethingOnceOnly(); }) 

Il appelait mon doSomethingOnceOnly() deux fois, et je pensais que ce devait être le double sélecteurs dans l'argument $. J'ai simplement fait 2 sélecteurs différents et ça a bien fonctionné. Donc, comme ça

$('#id').animate({width: '200px'}, 100); 
$('#id2').animate({width: '200px'}, 100, function() { doSomethingOnceOnly();); 
+0

Oui, comment avez-vous résoudre le problème .. J'ai une bidouille horrible, il est un setTimeout .. Je veux que ce soit générique et ne pas compter sur le calendrier ... –

+0

Je pense que je me suis arrêté enchaînant l'Animer () Je vais éditer ma réponse – alex

+0

IC, d'accord .. Merci Alex –

2

L'utilisation d'un drapeau pour contrôler le déclencheur a fait l'affaire pour moi.

var targetOffset = 0; 
var allow_trigger = true; 
$('html,body').animate({scrollTop: targetOffset}, 'slow', function() { 
    if (allow_trigger) { 
     allow_trigger = false; 
     doSomethingOnlyOnce(); 
    } 
}); 
+0

Merci cela a fonctionné parfaitement quand je voulais faire défiler ma première erreur sur un formulaire et ensuite le mettre en évidence une fois et a été surpris qu'il l'a souligné deux fois ... Je me demande pourquoi tous les effets scrollTo utilisent $ ('html, body') règle. vous avez toujours un code HTML et un corps. Pourquoi la «double couverture»? – armyofda12mnkeys