2010-01-13 5 views
1

Veuillez consulter http://jsbin.com/omuqo pour une démonstration de ce problème.Jitter dans l'implémentation de Jquery Accordion

Lorsque vous ouvrez un panneau en cliquant sur la poignée, les panneaux ci-dessous bougent légèrement tout au long de l'animation.

Dans la démonstration, les panneaux ci-dessous doivent rester complètement immobiles puisque tous les panneaux ont la même hauteur. Lorsque vous avez un accordéon plus complexe avec des panneaux de hauteur variable, ajoutez un assouplissement et ainsi de suite, la gigue est encore visible de différentes manières.

Pour déboguer, j'ai abandonné le plugin d'accordéon dans Jquery UI et mis en place le mien, suivant les conseils here.

Voici le code complet si jsbin ne fonctionne pas.

Le code HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<title>Sandbox</title> 
<meta http-equiv="Content-type" content="text/html; charset=utf-8" /> 
<style type="text/css" media="screen"> 
* { margin: 0; padding: 0; } 
body { background-color: #fff; font: 16px Helvetica, Arial; color: #000; } 
dt { background-color: #ccc; } 
dd { height: 100px; } 
#footer { background-color: #ff9; } 
</style> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script> 
</head> 
<body> 
    <dl> 
    <dt>Handle</dt> 
    <dd id="1">Content</dd> 
    <dt>Handle</dt> 
    <dd id="2">Content</dd> 
    <dt>Handle</dt> 
    <dd id="3">Content</dd> 
    <dt>Handle</dt> 
    <dd id="4">Content</dd> 
    </dl> 
    <div id="footer"> 
    Some more content 
    </div> 
</body> 
</html> 

Et le Javascript:

$.fn.accordion = function() { 
    return this.each(function() { 
    $container = $(this); 

    // Hijack handles. 
    $container.find("dt").each(function() { 
     var $header = $(this); 
     var $content = $header.next(); 

     $header 
     .click(function() { 
      $container 
      .find("dd:visible") 
      .animate({ height: 0 }, { duration: 300, complete: function() { 
       $(this).hide(); 
       } 
      }); 
      if(!$content.is(":visible")) { 
      $content 
       .show() 
      $content 
       .animate({ height : heights[$content.attr("id")] }, { duration: 300 }); 
      } 
      return false; 
     }); 
    }); 

    // Iterate over panels, save heights, hide all. 
    var heights = new Object(); 
    $container.find("dd").each(function() { 

     $this = $(this); 
     heights[$this.attr("id")] = $this.height(); 
     $this 
     .hide() 
     .css({ height : 0 }); 
    }); 
    }); 
}; 

$(document).ready(function() { 
    $("dl").accordion(); 
}); 

Pour voir une surface lisse mise en œuvre de l'accordéon, consultez la page d'accueil de Muxtape.

Un conseil?

+0

J'ai testé dans Safari, Chrome, IE8 et FireFox, et je ne vois pas de gigue - aucun effet secondaire du tout. – queen3

+0

Ouvrez un panneau, puis regardez le pied de page jaune lorsque vous faites glisser un autre panneau. Ça ne devrait pas bouger mais ça le fait. –

Répondre

3

Il semble que j'ai une solution. Synchroniser par ancrage à une transition externe indépendante via le rappel d'étape. Here est une démo de la nouvelle méthode.

Ce fut un vrai casse-tête!

Le javascript:

$.fn.accordion = function() { 
    return this.each(function() { 
    $container = $(this); 

    // Hijack handles. 
    $container.find("dt").each(function() { 
     var $header = $(this); 
     var $selected = $header.next(); 

    $header 
     .click(function() { 
      if ($selected.is(":visible")) { 
      $selected 
       .animate({ height: 0 }, { duration: 300, complete: function() { 
       $(this).hide(); 
       } 
      }); 
      } else { 
      $unselected = $container.find("dd:visible"); 
      $selected.show(); 
      var newHeight = heights[$selected.attr("id")]; 
      var oldHeight = heights[$unselected.attr("id")]; 

      $('<div>').animate({ height : 1 }, { 
       duration : 300, 
       step  : function(now) { 
       var stepSelectedHeight = Math.round(newHeight * now); 
       $selected.height(stepSelectedHeight); 
       $unselected.height(oldHeight + Math.round((newHeight - oldHeight) * now) - Math.round(newHeight * now)); 
       }, 
       complete : function() { 
       $unselected 
        .hide() 
        .css({ height : 0 }); 
       } 
      }); 
      } 
      return false; 
     }); 
    }); 

    // Iterate over panels, save heights, hide all. 
    var heights = new Object(); 
    $container.find("dd").each(function() { 

     $this = $(this); 
     $this.css("overflow", "hidden"); 
     heights[$this.attr("id")] = $this.height(); 
     $this 
     .hide() 
     .css({ height : 0 }); 
    }); 
    }); 
}; 

$(document).ready(function() { 
    $("dl").accordion(); 
}); 
+0

Bonjour J'ai un sujet de suivi sur ce sujet si vous pouviez le voir? http://stackoverflow.com/questions/5266849/problem-with-jquery-accordian-and-jitter-modification – Paul

0

Il semble que cela a à voir avec le fait que les deux animations parallèles (un panneau qui sort et d'autres qui se déplacent) de l'accordéon ne sont pas synchronisées.

Apparemment, il n'y a pas de façon établie de synchroniser les animations dans Jquery pour le moment.

Voir here et here pour plus d'informations.

Frustrant!

Questions connexes