【问题标题】:Jitter in Jquery Accordion ImplementationJquery Accordion 实现中的抖动
【发布时间】:2010-01-13 12:50:55
【问题描述】:

请查看http://jsbin.com/omuqo 以获取此问题的演示。

当您通过单击手柄打开面板时,下方的面板会在整个动画过程中略微抖动。

在演示中,下面的面板应该完全保持静止,因为所有面板的高度都相同。当您有一个具有不同高度的面板的更复杂的手风琴时,添加缓动等等,抖动仍然以各种方式可见。

为了调试,我放弃了 Jquery UI 中的手风琴插件,并按照here 的建议实现了自己的插件。

这里是完整的代码应该 jsbin 不工作。

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>

还有 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();
});

要查看手风琴的顺利实现,请查看Muxtape 的主页。

有什么建议吗?

【问题讨论】:

  • 我在 Safari、Chrome、IE8 和 FireFox 中进行了测试,我没有看到任何抖动 - 完全没有副作用。
  • 打开一个面板,然后在滑出另一个面板时观察黄色页脚。它不应该移动,但它会移动。

标签: javascript jquery jquery-ui


【解决方案1】:

看来我有办法了。通过步骤回调与独立的外部转换挂钩来进行同步。 Here 是新方法的演示。

这真是令人头疼!

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

【讨论】:

【解决方案2】:

这似乎与手风琴中的两个平行动画(一个面板出现,另一个移开)不同步有关。

显然,目前在 Jquery 中没有既定的方式来同步动画。

请参阅here 和here 了解更多信息。

令人沮丧!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 2013-11-17
    • 2017-07-01
    • 1970-01-01
    相关资源
    最近更新 更多