Jquery 手风琴 - 用动画打开内容

Jquery Accordion - Make content open with animation

我有这个 JSfiddle:https://jsfiddle.net/07fdq3t1/5/

它几乎是完美的,除了我想把它放在以动画方式显示内容的地方。现在它突然打开,但我想让它慢慢打开。使其到达视口顶部的动画效果很好,但我需要它到达当有人单击元素时内容打开缓慢的位置。

有什么想法吗?

<script>
$(document).ready(function() {
    $('.accordion').click(function(){
        if($(this).next('.container').is(':visible')) {
            $(this).removeClass('show');
            $(this).next('.container').slideUp();
        }
        else {
            $('.accordion').find('.container:visible').slideUp();
            $('.accordion').removeClass('show');
            $(this).addClass('show');
            $(this).next('.container').slideDown();
            $('html, body').animate({
                scrollTop: $(this).offset().top
            }, 200);
        }         
    });
});
</script>

<div class="accordion">Heading<span></span></div>
    <div class="container">
        <div class="content">
            <div>Sample Content</div>
            <p>Content here....</p>
        </div>
    </div>
<div class="accordion">Heading<span></span></div>
    <div class="container">
        <div class="content">
            <div>Sample Content</div>
            <p>Content here....</p>
        </div>
    </div>

刚刚让你的幻灯片在完成时删除显示 class 并在最后使用 slideDown 函数显示你的容器。

$(document).ready(function() {
    $('.accordion').click(function(){
        if($(this).next('.container').is(':visible')) {
            var self = $(this);
            $(this).next('.container').slideUp(800,function() {
                self.removeClass('show');
            });
        }
        else {
            $('.accordion').find('.container:visible').slideUp();
            $('.accordion').removeClass('show');
            $(this).addClass('show');
            $(this).next('.container').slideDown();
            $('html, body').animate({
                scrollTop: $(this).offset().top
            }, 200);
            $(this).slideDown();
        }         
    });
});

这里是 运行: https://jsfiddle.net/07fdq3t1/6/

是的,只需使用 slideUp()slideDown() 方法,而不是简单地添加 show class.

Updated fiddle here

好的。这是我尝试解决您的问题。看看下面的 fiddle 或片段。

JSFiddle.

片段:

var accordions=null;
var containers=null;
var slideDuration=400;
var scrollDuration=400;
var body=null;
var classNameShow='show';
var classNameAccordion='.accordion';
var classNameContainer='.container';
var dataOffsetTop='offsetTop';
$(document).ready(function(){
 body=$('html, body');
 accordions=$(classNameAccordion);
 containers=$(classNameContainer);
 accordions.each(function(){
  var openedAccordions=accordions.filter(function(){return $(this).hasClass(classNameShow);});
  openedAccordions.removeClass(classNameShow);
  $(this).data(dataOffsetTop,$(this).offset().top);
  openedAccordions.next(classNameContainer).stop(true).slideDown({
   duration:slideDuration,
   complete:function(){openedAccordions.addClass(classNameShow);}
  });
 });
 accordions.click(function(){
  var currentAccordion=$(this);
  var currentContainer=$(this).next(classNameContainer);
  var openedAccordions=accordions.filter(function(){return $(this).hasClass(classNameShow);});
  if(!currentAccordion.hasClass(classNameShow)){
   currentContainer.stop(true).slideDown({
    duration:slideDuration,
    complete:function(){currentAccordion.addClass(classNameShow);}
   });
   body.stop(true).animate({scrollTop:currentAccordion.data(dataOffsetTop)},scrollDuration);
  }else{
   currentContainer.stop(true).slideUp({
    duration:slideDuration,
    complete:function(){currentAccordion.removeClass(classNameShow);}
   });
  }
  containers.not(currentContainer).stop(true).slideUp({
   duration:slideDuration,
   complete:function(){openedAccordions.removeClass(classNameShow);}
  });
 });
});
.accordion {
 margin: 0;
 padding: 10px;
 height: 20px;
 border-top: #f0f0f0 1px solid;
 background: #cccccc;
 font-family: Arial, Helvetica, sans-serif;
 text-decoration: none;
 text-transform: uppercase;
 color: #000;
 font-size: 1em;
}
.accordion span {
 background: #000;
 color: #fff;
}
.show span {
 display: block;
 float: right;
 padding: 10px;
}
.accordion span {
 display: block;
 float: right;
 background: url(http://www.snyderplace.com/demos/images/plus.png) center center no-repeat;
 padding: 10px;
}
.show span {
 background: url(http://www.snyderplace.com/demos/images/minus.png) center center no-repeat;
}
div.container {
 padding: 0;
 margin: 0;
 display: none;
}
div.content {
 background: #f0f0f0;
 margin: 0;
 padding: 10px;
 font-size: .9em;
 line-height: 1.5em;
 font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
}
div.content ul, div.content p {
 margin: 0;
 padding: 3px;
}
div.content ul li {
 list-style-position: inside;
 line-height: 25px;
}
div.content ul li a {
 color: #555555;
}
div.show + .container {
 display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p></div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion show">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
 <div class="content">
  <div>Sample Content</div>
  <p>Content here....</p>
 </div>
</div>

总结:(不是真的)

  • 变量首先被初始化。的价值观 在此过程中,根据需要设置变量。
  • 第一个each块是根据[=71]计算目标scrollTop值=]offset.top()个手风琴元素的all个位置。然后将每个 accordion 元素存储在 data() 属性 中。
  • 它首先收集当前应用了 show class 的元素,并将它们存储在名为 [=71 的变量中=]openedAccordions.
  • 然后它暂时从他们那里删除这个showclass。
  • 获取每个元素的 offset.top() 位置并使用方便的 data() 存储在元素本身jQuery.
  • 提供的方法
  • 而不是简单地使用addClass()方法重新应用showclass,我们实际上 animate 使用 slideDown() 方法,只有在动画完成后,我们使用 addClass().
  • 应用 show
  • 这很重要,因为使用 addClass() 的简单直接应用 show 没有动画会产生不需要的故障 作为用户,您第一次与整个组件交互。 故障 基本上是您第一个已经可见的 container 元素,它会立即消失,没有动画。
  • 上述方法的原因是因为当事情是动画时,浏览器将 return 当前 offset().top 任何给定手风琴元素的位置可能不完全是我们需要的,即动画可能正在进行中,并且 offset().top 的计算结果可能是错误的,因此浏览器将滚动到不需要的位置。我希望你明白我想在这里说什么。
  • 继续...
  • 单击任何 accordion 元素后,将定义一些内部变量并设置它们的值。
  • 一个典型的 if 子句检查元素是否应用了名为 show 的 class
  • 这是您采用的方法与我采用的方法的根本区别。我没有检查 :visible 状态,而是选择简单地查找元素上是否存在 class'。
  • if 子句的其余部分应该是不言自明的。
  • 最后一点是另一个有趣的地方。
  • 我正在使用 slideUp 为元素设置动画,因此 openedAccordions 元素可以隐藏除了刚刚被点击的那个。我希望我在这里说得有道理。
  • 就是这样。如果您有任何问题,请告诉我。

希望这对您有所帮助。

P.S。我想对我来说最酷的一点是它如何在快速点击时重新调整。尝试增加 scrollDurationslideDuration 值以使所有动画变慢并单击随机 accordion个元素看看​​我说的重新调整.

是什么意思