所以我找到了解决方案。我只是在触发关闭下拉菜单之前将maxHeight 设置为offsetHeight。
我还需要使用 0 毫秒的 setTimeout 来触发关闭它,尽管在运行以下函数之后。
export function retreatDropdown(e: HTMLElement) {
e.style.maxHeight = `${e.offsetHeight}px`;
}
我可以做一个类似的技巧来打开动画,但在打开之前你不会知道正确的maxHeight,所以我猜这更棘手(但不如关闭动画 IMO 重要)。
编辑:关闭/打开下拉菜单的完整(TypeScript)解决方案
const defaultTransitionTime = 200;
export function toggleDropdown(
e: HTMLElement,
value: boolean = null,
toggleAction: () => void = null // Function that toggles true/false for accordion open
) {
if (value) {
openDropdown(e, toggleAction);
} else {
retreatDropdown(e, toggleAction);
}
}
export function openDropdown(
e: HTMLElement,
openAction: () => void = null
) {
if (openAction) setTimeout(() => openAction(), 0);
e.style.display = "block";
setTimeout(() => {
const offsetHeight = e.offsetHeight;
e.style.maxHeight = "0px";
setTimeout(() => {
e.style.maxHeight = `${offsetHeight}px`;
}, 5);
}, 5);
setTimeout(() => {
e.style.maxHeight = "none";
}, defaultTransitionTime);
}
export function retreatDropdown(
e: HTMLElement,
closeAction: () => void = null
) {
e.style.maxHeight = `${e.offsetHeight}px`;
if (closeAction) setTimeout(() => closeAction(), 0);
}
下拉 CSS 类:
.dropdown {
transition: opacity 200ms linear, max-height 200ms linear;
will-change: opacity, max-height;
}
Angular ngStyle(应用于手风琴的打开/关闭):
elementStyle(e: HTMLElement) {
return this.isOpen(HTMLElement) // I use a map of booleans for open state here...
? { display: "block", "max-height": "none" }
: { "max-height": 0, opacity: 0 };
}