javascript - 移动动画手风琴中的所有元素
问题描述
一个手风琴动画,其中Animate Plus
包含包含dl
和legend
元素fieldset
。一切都按预期工作,除了fieldset
不扩展并且legend
不与其余元素一起移动。
我想fieldset
通过增加相同的量平滑地调整高度dl
。
我的 JavaScript 代码:
const accordions = Array.from(document.querySelectorAll("dl")).map(dl => ({
element: dl,
translate: 0
}))
const getButtons = accordion => Array.from(
accordion.element.getElementsByTagName("button"),
element => ({
element,
translate: 0
})
)
const timing = {
easing: "out-quartic",
duration: 400
}
const clear = element =>
Object.values(element.attributes).forEach(({ name }) =>
element.removeAttribute(name)
)
const hide = async (accordion, buttons, collapsing) => {
const objects = buttons.filter(({ translate }) => translate)
const direction = "reverse"
rotate(collapsing.previousElementSibling.lastElementChild, direction)
slide(accordion, objects)
await fold(collapsing, direction)
clear(collapsing)
}
const show = (accordion, buttons, expanding) => {
const button = expanding.previousElementSibling.lastElementChild
const index = buttons.findIndex(({ element }) => element == button)
const objects = buttons.slice(index + 1)
const { height } = expanding.getBoundingClientRect()
expanding.className = "open"
rotate(button)
slide(accordion, objects, height)
fold(expanding)
}
const slide = (accordion, array, to = 0) => {
center(accordion, to)
animate({
...timing,
elements: array.map(({ element }) => element.parentElement),
transform(index) {
const object = array[index]
const from = object.translate
object.translate = to
return [`translateY(${from}px)`, to]
}
})
}
const center = (accordion, height) => {
const from = accordion.translate
const to = Math.round(-height / 2)
accordion.translate = to
animate({
...timing,
elements: accordion.element,
transform: [`translateY(${from}px)`, to]
})
}
const fold = async (content, direction = "normal") =>
await animate({
...timing,
direction,
elements: content,
opacity: [0, 1],
transform: ["scaleY(0)", 1]
})
const rotate = ({ lastElementChild: elements }, direction = "normal") =>
animate({
elements,
direction,
easing: "out-cubic",
duration: 600,
transform: ["rotate(0turn)", 0.5]
})
const toggle = (accordion, buttons) => async ({ target }) => {
const collapsing = accordion.element.querySelector(".open")
const expanding = target.parentElement.nextElementSibling
if (collapsing) await hide(accordion, buttons, collapsing)
if (collapsing != expanding) show(accordion, buttons, expanding)
}
accordions.forEach(accordion => {
const buttons = getButtons(accordion)
buttons.forEach(
({ element }) => element.addEventListener("click", toggle(accordion, buttons))
)
})
import animate from "https://cdn.jsdelivr.net/npm/animateplus@2/animateplus.js"
我的手风琴完整代码可以在 CodePen 上找到:
解决方案
问题都源于您拥有的事实:
dd {
position: absolute;
/* more styles */
}
本质上,这使得在计算其父元素的高度时忽略该元素的高度。
我不熟悉您正在使用的库,但是快速修改以删除它,在隐藏时将 max-height 设置为 0,然后将该高度设置scrollHeight
为内容的高度(即内容的高度) maxHeight 被忽略)。
https://codepen.io/anon/pen/xMXbJX
dd {
opacity: 0;
max-height: 0;
}
const fold = async (content, direction = "normal") => {
const scrollHeight = content.scrollHeight
await animate({
...timing,
direction,
elements: content,
opacity: [0, 1],
maxHeight: ['0px', scrollHeight + 'px'],
transform: ["scaleY(0)", 1]
})
}
推荐阅读
- excel - Excel:计算一组多个条件的唯一日期
- sql-server - SQL Server 跟踪未捕获所有审核添加数据库用户事件
- reporting-services - SSRS - 根据参数值对报表列进行排序
- javascript - document.body.removeEventListener 移除所有点击事件监听器(不是指定函数)为什么?
- java - 恢复 jenkins 根文件夹 config.xml 文件
- php - 如何在不添加空格的情况下使用 PHP DOMDocument saveHTML($node)?
- python - Python中的类对象编程
- javascript - 将动态 HTML 类存储为 JS 变量
- sql - 在 SQL Server 中找到最低的两个最小值并找到两者之间的差异?
- simulink - 离散低通滤波器