HTML <details>
元素提供了一种创建可展开和可折叠内容部分的简单方法。 让我们探索如何通过平滑的 CSS 过渡来增强此功能,并解决单独使用 CSS 的局限性。
基本的 <details>
实现如下所示:
<code class="language-html"><details> <summary>Click to expand</summary> <p>This is the content.</p> </details></code>
虽然这可行,但仅使用 CSS 添加平滑过渡证明具有挑战性。 例如,以下 CSS 不会产生所需的效果:
<code class="language-css">details#my-details { transition-duration: 300ms; }</code>
要实现平滑的切换过渡,JavaScript 是必需的。
关键是将 <details>
元素中的内容与另一个元素(此处为 <div>
)包裹起来。 这使我们能够单独定位内容并为其设置动画:
<code class="language-html"><details id="my-details"> <summary>Click to expand</summary> <div> <p>This is the content.</p> </div> </details></code>
以下 JavaScript 代码将处理动画:
<code class="language-javascript">const details = document.getElementById("my-details"); const summary = details.firstElementChild; const content = summary.nextElementSibling; let isAnimating = false; summary.onclick = (ev) => { ev.preventDefault(); if (isAnimating) return; const contentHeight = content.getBoundingClientRect().height; isAnimating = true; // Closing <details> if (details.open) { return content .animate( { height: [contentHeight + 'px', '0px'] }, { duration: 300 } ) .finished .then(() => details.open = isAnimating = false); } // Opening <details> details.open = true; content.animate( { height: ['0px', contentHeight + 'px'] }, { duration: 300 } ).finished.then(() => isAnimating = false); };</code>
此 JavaScript 代码使用 animate()
方法来控制内容包装器的高度过渡。 请注意,在某些情况下,可能需要将 overflow: hidden;
添加到内容包装器的 CSS 中才能获得最佳结果。
JavaScript 代码阻止默认的 <summary>
行为,获取内容高度,然后使用 animate()
方法根据 <details>
是打开还是关闭来平滑调整高度。 isAnimating
变量可防止多个动画同时运行。
isAnimating
标志可确保一次仅运行一个动画,从而防止用户在动画进行过程中重复单击时发生冲突和意外行为。
此技术为 <details>
元素提供了平滑、受控的过渡。 虽然此示例使用高度动画,但 animate()
方法可以适用于为其他 CSS 属性设置动画,从而提供了一种创建引人入胜的用户交互的通用方法。 请记住,对于更高级的动画,建议更深入地研究 animate()
方法及其功能。
以上是我如何切换到