JS+CSS手风琴动画效果
手风琴动画效果:当点击某个选项卡时,该选项卡展示内容,其他选项卡的内容收起,无论展示还是收起都带有过渡效果
效果图如下:
思路:为每个选项卡设置点击事件,修改dom元素样式
难点:过渡动画的实现。刚开始我使用display:block
或display:none
控制内容的显示与隐藏,但是发现display并没有动画效果,后来想使用height
,但元素高度不固定(高度由内容撑开),也没法实现动画效果。
最后百度找到一个解决方法:使用maxHeight作为过渡效果的CSS属性,使用css设置内容元素的maxHeight为0,并且使用overflow:hidden隐藏溢出内容。当点击选项卡时,使用JS获取内容元素的真实高度(dom.scrollHeight),再把真实高度赋值给内容元素的maxHeight即可。
代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <div class="container"> <h2>手风琴动画</h2> <button class="accordion">选项1</button> <div class="panel"> <ul> <li> <a href="">Overview</a> </li> <li> <a href="">Microservices</a> </li> <li> <a href="">Overview</a> </li> </ul> </div> <button class="accordion">选项2</button> <div class="panel"> <ul> <li> <a href="">Quickstart</a> </li> </ul> </div> <button class="accordion">选项3</button> <div class="panel"> <ul> <li> <a href="">Events</a> </li> <li> <a href="">Team</a> </li> </ul> </div> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| ul{ list-style: none; padding: 0; margin: 0; } a { text-decoration: none; color: black; } .container { width: 600px; margin: 0 auto; text-align: center; background: #191e1e; color: white; } button.accordion { background-color: #191e1e; color: white; cursor: pointer; padding: 16px; width: 100%; border: none; text-align: left; outline: none; font-size: 18px; transition: 0.4s; } button.accordion.active, button.accordion:hover { background-color: rgb(110, 109, 109); } div.panel { max-height: 0; overflow: hidden; transition: max-height 0.2s ease-out; } .panel a{ background: #191e1e; display: block; padding: 10px 20px; color: #98afae; text-align: left; font-size: 16px; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| let acc = document.querySelectorAll('.accordion'); let panelList = document.querySelectorAll('.panel')
acc.forEach((ele,index)=>{ ele.onclick = function(){ this.classList.toggle('active'); let panel = panelList[index]; if(panel.style.maxHeight){ panel.style.maxHeight = null }else{ panel.style.maxHeight = panel.scrollHeight+"px"; } acc.forEach((e,i)=>{ if(index!=i){ ele.classList.remove('active') panelList[i].style.maxHeight = null } }) } })
|