【问题标题】:Moving all elements in an animated accordion移动动画手风琴中的所有元素
【发布时间】:2019-02-02 21:20:18
【问题描述】:

使用Animate Plus 制作动画的手风琴在fieldset 中包含dllegend 元素。除了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 上找到:

https://codepen.io/anon/pen/ZwKMZx

【问题讨论】:

  • 您是否尝试过调整字段集的高度并将您的 dt 标签移动到下方?
  • css 变换不会影响 dom 布局(高度/宽度),请尝试更改元素的实际高度

标签: javascript css animation ecmascript-6 animateplus


【解决方案1】:

问题都源于您拥有的事实:

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]
  })
}

【讨论】:

  • 嗨,戴夫。感谢您花时间回答。在您的解决方案中,fieldset 和其他元素都没有动画。因此,使用 Animate Plus 的全部意义就消失了。
  • ...是的,正如我所说,它会一直跳跃,直到你为高度添加动画。所以,要清楚 - 弄清楚如何使用您正在使用的动画库为高度设置动画。我会想象它的工作方式与您为不透明度设置动画的方式相同。如果您在从 0 到 auto 动画时遇到问题,那么您应该将 height 设置为 auto,并将 maxHeight 属性从 0 动画到您想要的任何大数字。
猜你喜欢
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 2019-11-12
  • 2016-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多