我想为 div 的高度设置动画。这通常在 CSS 中通过为 max-height
属性设置动画来完成。
但是我需要在 JS 中执行此操作。 div 填充了经常变化的动态内容,因此无法提前知道实际高度。
这是一个 jsfiddle:https://jsfiddle.net/vpknxuk8/
var box = document.getElementById("box");
var button = document.getElementById("button");
var expanded = true;
button.addEventListener('click', function() {
if (expanded) {
box.style.maxHeight = 0;
expanded = false;
} else {
box.style.maxHeight = "";
expanded = true;
}
});
#box {
margin-top: 20px;
border: 1px solid black;
background-color: #4f88ff;
width: 200px;
transition: max-height 0.25s linear;
overflow: hidden;
}
<button id="button">Click</button>
<div id="box">
Hello World<br>
This is dynamic content<br>
The actual height won't be known ahead of time
</div>
盒子应该在高度 0 和它的默认高度之间转换,但由于某些原因它没有动画。
StackOverflow 上此问题的唯一其他版本与纯 CSS 解决方案或 jQuery 解决方案有关。
最佳答案
不要使用max-height
...好吧,除非你想采用CSS-only 草率的解决方案会产生延迟间隙问题 - ...这就是为什么你首先重新使用 JS,希望如此
因此,请改用height
和transition: height
function slidetoggle() {
document.querySelectorAll(this.getAttribute('data-slidetoggle')).forEach(el => {
const ch = el.clientHeight,
sh = el.scrollHeight,
isCollapsed = !ch,
noHeightSet = !el.style.height;
el.style.height = (isCollapsed || noHeightSet ? sh : 0) + "px";
if (noHeightSet) return slidetoggle.call(this);
});
}
document.querySelectorAll("[data-slidetoggle]").forEach(el => el.addEventListener('click', slidetoggle));
#box1,
#box2 {
overflow: hidden;
margin-bottom: 20px;
background-color: #4f88ff;
width: 200px;
transition: height 0.5s;
}
<button data-slidetoggle="#box1">Toggle Box 1</button>
<div id="box1">
Hello World<br> This is dynamic content<br> The actual height won't be<br> known ahead of time
</div>
<button data-slidetoggle="#box2">Toggle Box 2</button>
<div id="box2">
Hello World<br> This is dynamic content<br> The actual height won't be<br> known ahead of time<br> bla
<br> bla
<br> bla
</div>
提示:如果您需要填充,我的建议是将您的内容包装到另一个子框中 - 使用填充。
上面的代码是概念性的和最小的 - 有很大的改进空间,但希望你明白了。
为什么要用上面的解释,为什么不使用下面的:
如果我们不设置初始高度,CSS height-transition 将无法工作。
所以基本上是在点击时——如果这样的高度不存在,我们需要通过 JS 来设置它。
设置了这样的高度后,转换仍然无法工作,因为浏览器没有时间计算这样的元素的盒子模型 - 到转换自:
// (INVALID DEMO)
//
// Say the element is expanded.
// We need a height to transition-from
el.height = calculatedHeight +"px"; // set CSS height to the calculated value
// Transition to 0px height....
el.height = 0 +"px";
// NO DEAL. our element just snapped to 0 without transition
因此我们需要驻留在某种回调。
一种常见的(但草率的方式)是使用 setTimeout()
回调
// (INVALID DEMO)
//
// Say the element is expanded.
// We need a height to transition-from
el.height = calculatedHeight +"px"; // set CSS height to the calculated value
// Transition to 0px height giving the browser some ready-state hack
setTimeout(function() {
// Eventually the box model will be calculated
el.height = 0 +"px";
}, 0); // <<< PROBLEM: Should we use 0 ? 10? 100? 1000?
// and our element beautifully transitioned to 0 height.
// Eventually :(
关于javascript - 用纯 JS 动画最大高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44467909/