[英]Moving all elements in an animated accordion
使用Animate Plus
制作動畫的手風琴在fieldset
包含dl
和legend
元素。 一切都按預期工作,除了fieldset
不展開並且legend
不隨其余元素移動。
我想通過增加相同的 ammount dl
來平滑調整fieldset
高度。
我的 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
內容的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]
})
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.