如何使用WAAPI对细节元素进行动画动画
使用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中文网其他相关文章!

热AI工具

Undress AI Tool
免费脱衣服图片

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

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

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

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

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Themaindifferencesbetweendisplay:inline,block,andinline-blockinHTML/CSSarelayoutbehavior,spaceusage,andstylingcontrol.1.Inlineelementsflowwithtext,don’tstartonnewlines,ignorewidth/height,andonlyapplyhorizontalpadding/margins—idealforinlinetextstyling

设置访问过链接的样式能提升用户体验,尤其在内容密集型网站中帮助用户更好导航。1.使用CSS的:visited伪类可定义已访问链接样式,如颜色变化;2.注意浏览器出于隐私限制仅允许修改部分属性;3.颜色选择应与整体风格协调,避免突兀;4.移动端可能不显示该效果,建议结合其他视觉提示如icon辅助标识。

要使用CSS创建响应式图片,主要可通过以下方法实现:1.使用max-width:100%和height:auto让图片在保持比例的同时自适应容器宽度;2.结合HTML的srcset和sizes属性智能加载适配不同屏幕的图片源;3.利用object-fit和object-position控制图片裁剪与焦点展示。这些方法共同确保图片在不同设备上清晰、美观地呈现。

不同浏览器对CSS解析存在差异,导致显示效果不一致,主要包括默认样式差异、盒模型计算方式、Flexbox和Grid布局支持程度及某些CSS属性行为不一致。1.默认样式处理不一致,解决方法是使用CSSReset或Normalize.css统一初始样式;2.旧版IE的盒模型计算方式不同,建议统一使用box-sizing:border-box;3.Flexbox和Grid在边缘情况或旧版本中表现有差异,应多测试并使用Autoprefixer;4.某些CSS属性行为不一致,需查阅CanIuse并提供降级

opacity是CSS中用于控制元素整体透明度的属性,取值范围为0(完全透明)到1(完全不透明)。1.常用于图片hover淡出效果,通过设置opacity过渡增强交互体验;2.制作背景遮罩层提升文字可读性;3.控制按钮或图标在禁用状态下的视觉反馈。需注意它会影响所有子元素,且与rgba不同,后者仅影响指定颜色部分。搭配transition可实现平滑动画,但频繁使用可能影响性能,建议结合will-change或transform使用。合理应用opacity能增强页面层次感和交互性,但应避免干扰用户

accent-color是CSS中用于自定义复选框、单选按钮和滑块等表单元素高亮颜色的属性;1.它直接改变表单控件选中状态的默认颜色,如将复选框的蓝色勾选标记改为红色;2.支持的元素包括type="checkbox"、type="radio"和type="range"的输入框;3.使用accent-color可避免复杂的自定义样式和额外DOM结构,保持原生可访问性;4.现代浏览器普遍支持,旧浏览器需降级处理;5.设置accent-col

The:has()pseudo-classinCSSallowstargetingaparentelementbasedonitschildelements.Itworksbyusingthesyntaxparent:has(child-selector)toapplystylesconditionally.Forexample,div:has(img)appliesstylestoadivcontaininganimage.Multipleselectorscanbeusedwithcomma

为什么设置了100px宽度的盒子会显示更宽?因为默认使用的是content-box模型,实际宽度包括内容、padding和border。1.默认情况下,box-sizing是content-box,设置的width仅指内容区域,padding和border会额外增加整体宽度;2.使用border-box可让设定的width包含内容、padding和border,布局更直观;3.推荐全局设置box-sizing:border-box,避免布局错位,尤其适合响应式设计;4.特殊场景下可使用conte
