天天看点

实现 collpase 折叠的几种方法

​​https://carlanderson.xyz/how-to-animate-on-height-auto/​​

JS方法解析

<!--
* @file: description
* @author: huhao03
* @Date: 2021-09-27 15:03:30
* @LastEditors: huhao03
* @LastEditTime: 2021-09-27 16:16:57
-->
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.collapsible {
overflow: hidden;
transition: all 0.5s ease-in-out;
height: auto;
}

.collapsible.collapsed {
height: 0;
}
</style>
</head>

<body>
<div>
<button class="button">Collapse</button>
<div class="content">
<p class="collapsible">
This is a block of text that is collapsed through JavaScript. It is more complicated than using
max-height with similar performance. The transition timings are now fixed but we've introduced some
coupling between our CSS and JS.
</p>
<p>
Praesent nec feugiat enim. In vitae elementum erat. Lorem ipsum dolor sit amet, consectetur adipiscing
elit. Pellentesque vitae lectus varius ipsum tempor maximus in ac eros. Mauris lacus lorem, elementum
non lacus vitae, interdum commodo odio.
</p>
</div>
</div>
</body>
<script>
const button = document.querySelector('.button');

button.addEventListener('click', () => {
 
const content = document.querySelector('.collapsible');

// 下面执行这个方法
expandElement(content, 'collapsed');
});      
function expandElement(elem, collapseClass) {
 
// collapseClass的值是collapsed
elem.style.height = ''; // A style declaration is reset by setting it to null or an empty string, e.g., elt.style.color = null. https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
// 先禁止transitiond的效果
elem.style.transition = 'none';

// 1 先获取当前的高度
const startHeight = window.getComputedStyle(elem).height;

 
// toggle是如果没有class就加上,如果有就去除
// Remove the collapse class, and force a layout calculation to get the final height
elem.classList.toggle(collapseClass);
// 下面获取高度,这个时候高度已经立刻改变了
const height = window.getComputedStyle(elem).height;      
// 然后把高度又设置回去, 但是这个时候height变量已经可以获取到toggleClass之后的高度了
// Set the start height to begin the transition
elem.style.height = startHeight;      
/*
window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
注意:若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()
*/      
// wait until the next frame so that everything has time to update before starting the transition
requestAnimationFrame(() => {
elem.style.transition = ''; // 在下一帧之前将transition重置,也就是style中写好的transition
// 将高度设置为我想变成的高度(toggleclass之后的高度)
elem.style.height = height
})
      
// Clear the saved height values after the transition
elem.addEventListener('transitionend', () => {
// transition之后将高度设置为默认的
elem.style.height = '';
// 移除transitioned这个回调
elem.removeEventListener('transitionend', arguments.callee); // callee是()=>{}这个函数本身..
});
}
</script>
</html>