使用Web Animations API为原生<details></details>
元素创建动画效果
网站上最常见的动画需求之一就是手风琴式展开收起效果。有趣的是,jQuery的slideDown()
函数早在2006年的第一个版本中就已经存在了。
本文将介绍如何使用Web Animations API为原生的<details></details>
元素创建动画效果。
HTML结构
首先,让我们看看实现此动画所需的HTML标记结构。
为了提高代码的可重用性,我们应该创建一个Accordion类。这样,我们就可以在页面上的每个 构造函数用于存储每个手风琴所需的数据。 在 此 此函数在收缩或展开动画结束时调用。如您所见,有一个参数 我们完成了代码的大部分工作! 剩下的就是为HTML中的每个 为了计算关闭高度和打开高度,我们需要确保 例如,不要尝试在 此外,不要在 就这样,我们使用JavaScript创建了一个漂亮的手风琴动画,无需任何库! 请注意,图片的路径 <details></details>
元素需要一个<summary></summary>
元素。<summary></summary>
是手风琴折叠时可见的内容。<details></details>
内的所有其他元素都是手风琴内部内容的一部分。为了方便动画效果的实现,我们将它们包裹在一个<details>
<summary>手风琴标题</summary>
<div class="content">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Modi unde, ex rem voluptates autem aliquid veniam quis temporibus repudiandae illo, nostrum, pariatur quae! At animi modi dignissimos corrupti placeat voluptatum!
</p>
</div>
</details>
Accordion类
<details></details>
元素上调用new Accordion()
。class Accordion {
constructor(el) {}
onClick(e) {}
shrink() {}
open() {}
expand() {}
onAnimationFinish(open) {}
}
构造函数
constructor()
constructor(el) {
this.el = el;
this.summary = el.querySelector('summary');
this.content = el.querySelector('.content');
this.animation = null;
this.isClosing = false;
this.isExpanding = false;
this.summary.addEventListener('click', (e) => this.onClick(e));
}
onClick()
onClick()
函数中,我们会检查元素是否正在进行动画(关闭或展开)。如果用户在元素正在动画时点击手风琴,我们需要进行此检查。如果点击速度过快,我们不希望手风琴从完全展开跳到完全关闭。<details></details>
元素在打开时,浏览器会为其添加一个open
属性。我们可以通过this.el.open
来获取该属性的值。onClick(e) {
e.preventDefault();
this.el.style.overflow = 'hidden';
if (this.isClosing || !this.el.open) {
this.open();
} else if (this.isExpanding || this.el.open) {
this.shrink();
}
}
shrink()
shrink()
函数使用WAAPI的.animate()
函数。您可以阅读MDN文档了解更多信息。WAAPI与CSS @keyframes
非常相似。我们需要定义动画的起始和结束关键帧。在本例中,我们只需要两个关键帧,第一个是元素的当前高度,第二个是手风琴关闭后的高度。当前高度存储在startHeight
变量中。关闭高度存储在endHeight
变量中,等于<summary></summary>
的高度。shrink() {
this.isClosing = true;
const startHeight = `${this.el.offsetHeight}px`;
const endHeight = `${this.summary.offsetHeight}px`;
if (this.animation) {
this.animation.cancel();
}
this.animation = this.el.animate({
height: [startHeight, endHeight]
}, {
duration: 400,
easing: 'ease-out'
});
this.animation.onfinish = () => this.onAnimationFinish(false);
this.animation.oncancel = () => this.isClosing = false;
}
open()
open()
函数在我们要展开手风琴时调用。此函数目前不控制手风琴的动画。首先,我们计算<details></details>
元素的高度,并使用内联样式将其应用于元素。完成后,我们可以设置其open
属性以使内容可见,但由于我们对元素设置了overflow: hidden
和固定高度,因此内容仍然隐藏。然后,我们等待下一帧调用expand()
函数并为元素创建动画。open() {
this.el.style.height = `${this.el.offsetHeight}px`;
this.el.open = true;
window.requestAnimationFrame(() => this.expand());
}
expand()
expand()
函数类似于shrink()
函数,但它不是从当前高度动画到关闭高度,而是从元素的高度动画到结束高度。结束高度等于<summary></summary>
的高度加上内部内容的高度。expand() {
this.isExpanding = true;
const startHeight = `${this.el.offsetHeight}px`;
const endHeight = `${this.summary.offsetHeight this.content.offsetHeight}px`;
if (this.animation) {
this.animation.cancel();
}
this.animation = this.el.animate({
height: [startHeight, endHeight]
}, {
duration: 400,
easing: 'ease-out'
});
this.animation.onfinish = () => this.onAnimationFinish(true);
this.animation.oncancel = () => this.isExpanding = false;
}
onAnimationFinish()
open
,在手风琴打开时设置为true
,允许我们设置元素上的open
HTML属性,因为它不再由浏览器处理。onAnimationFinish(open) {
this.el.open = open;
this.animation = null;
this.isClosing = false;
this.isExpanding = false;
this.el.style.height = this.el.style.overflow = '';
}
设置手风琴
<details></details>
元素使用我们的Accordion类。为此,我们使用<details></details>
标签上的querySelectorAll
,并为每个元素创建一个新的Accordion实例。document.querySelectorAll('details').forEach((el) => {
new Accordion(el);
});
注意
<summary></summary>
和内容始终具有相同的高度。<summary></summary>
打开时添加填充,因为这可能会导致动画过程中出现跳跃。内部内容也是如此——它应该具有固定高度,我们应该避免在打开动画过程中高度发生变化的内容。<summary></summary>
和内容之间添加边距,因为它不会计算高度关键帧。相反,直接在内容上使用填充来添加一些间距。总结
/uploads/20250331/174338369667e9ec90190a3.jpg
需要替换成实际的图片路径。 我无法访问或处理图片文件,所以只能保留原始格式。
以上是如何使用WAAPI对细节元素进行动画动画的详细内容。更多信息请关注PHP中文网其他相关文章!

这是我们在形式可访问性上进行的小型系列中的第三篇文章。如果您错过了第二篇文章,请查看“以:focus-visible的管理用户焦点”。在

本教程演示了使用智能表单框架创建外观专业的JavaScript表单(注意:不再可用)。 尽管框架本身不可用,但原理和技术仍然与其他形式的建筑商相关。

CSS盒子阴影和轮廓属性获得了主题。让我们查看一些在真实主题中起作用的示例,以及我们必须将这些样式应用于WordPress块和元素的选项。

Svelte Transition API提供了一种使组件输入或离开文档(包括自定义Svelte Transitions)时动画组件的方法。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

禅工作室 13.0.1
功能强大的PHP集成开发环境

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

Dreamweaver Mac版
视觉化网页开发工具

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具