【问题标题】:Jquery Accordion - Make content open with animationJquery Accordion - 使用动画打开内容
【发布时间】:2015-06-25 22:13:57
【问题描述】:

我有这个 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>

【问题讨论】:

    标签: jquery animation jquery-animate accordion


    【解决方案1】:

    好的。这是我解决您的问题的尝试。看看下面的 fiddle 或 sn-p。

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

    希望这会有所帮助。

    附:我想对我来说很酷的一点是它会如何在快速点击时重新调整。尝试增加 scrollDurationslideDuration 值以使所有动画变慢并单击随机 accordion 元素以查看我的意思是重新调整

    【讨论】:

    • 天哪,这真是太好了。非常感谢塔希尔!令人难以置信的工作。我想我有 2 个问题... 1. 有没有办法让多个手风琴可以在一个页面上并相互独立地运行?我在小提琴中尝试了几件事,但无法弄清楚。 2. 有没有办法让“滚动到视口顶部”功能仅适用于移动/触摸设备?不管怎样,非常感谢!
    • (1) 是的,我想这应该不是问题。应该只是使用正确的选择器(2) 为此,您可以查看Modernizr.touch 以查看您是否使用触摸设备并触发它。或者,您可以嗅探用户正在使用哪个浏览器(尽管不推荐)。互联网上有很多可用的东西。
    • 对于#1,有没有最好的方法呢?我想我可以复制整个脚本并重命名所有内容,但是有没有办法在这个单个脚本中放置多个选择器?有点像:var classNameShow=('show' || 'show2'); var classNameAccordion=('.accordion' || '.accordion2'); var classNameContainer=('.container' || '.container2');
    • 是的,它确实可以优化。你想为我创建一个示例 HTML / CSS(遵循我们所拥有的相同模式)然后我可以帮助你解决其中的 JS 位吗?
    • 我猜你不会再想要他们俩的 scrollTop 动画了?!
    【解决方案2】:

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

    Updated fiddle here

    【讨论】:

      【解决方案3】:

      刚刚让您的幻灯片在完成时删除了 show 类,并且在最后为您的容器使用了 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/

      【讨论】:

      • 这非常接近。在你的小提琴中,我注意到当我第二次单击一个元素时(之后它已经滑到顶部),然后它在打开时动画,但是有没有办法让它动画打开第一个我点击它的时间(当它滚动到顶部时)?所以基本上会同时出现两个动画(滚动到顶部和内容打开),但速度不同。
      猜你喜欢
      • 1970-01-01
      • 2013-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2017-08-20
      相关资源
      最近更新 更多