7.手风琴
手风琴效果其实就是通过JS改变元素的height,然后加上transition来让css动起来。
准备HTML结构
这里我们使用 dl , 因为 dt 刚好可以模拟标题, dd 模拟内容。
<div class="panel">
<dl>
<dt>One Item</dt>
<dd>One Item Content .</dd>
<dt>two Item</dt>
<dd>two Item Content .</dd>
<dt>3 Item</dt>
<dd>3 Item Content .</dd>
<dt>4 Item</dt>
<dd>4 Item Content .</dd>
</dl>
</div>准备css样式
*{margin: 0;padding: 0;}
.panel{
width: 480px;
min-height: 160px;
margin: 50px auto;
background: #eee;
}
.panel dt{
min-height: 40px;
line-height: 40px;
background: #f9f9f9;
padding-left: 10px;
cursor: pointer;
}
.panel dd{
padding-left: 10px;
height: 0;
overflow: hidden;
transition: height .5s;
}接下来书写我们的JS逻辑
首先我们为我们每一个 dt 绑定 click 事件
同样,我们使用 Array.from 将 NodeList转换为数组,通常能尽量不用for的我就不会用for。
nextElementSibling 代表下一个相邻的元素。
完成 toggle 函数
首先为我们要拿到所有的 dd 方便之后重置样式。 然后我们判断目标元素target上面的height, 初始的时候是 ''空字符串,之后就是0px了,当是0px的时候,就说明是关闭状态。
之后我们通过for of遍历所有 dd, 先清空一下未关闭的标签。
然后我们可以通过 Object.assign 来把后面的对象上面的属性拷贝到 target.style 上面去。
通常我们是无法获取一个隐藏元素的高的,所以我们首先把当前的 dd, 用绝对定位定位到屏幕外面去,之后我们就可以通过offsetHeight获取高度了。
有的人会问我为什么不直接用auto, 因为auto是不会产生动画的。 当然你也可以设置一个固定的高度。
之后我们,先把高度重置为0,之后在浏览器重新绘制下一帧的时候再设置高度。
你可以尝试一下去掉requestAnimationFrame,你同样会发现动画失效了。
我猜测可能是浏览器做了处理,短时间的切换属性height会被忽略掉。
Last updated