首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在手风琴上使用过渡效果

如何在手风琴上使用过渡效果
EN

Stack Overflow用户
提问于 2020-10-06 02:36:15
回答 1查看 242关注 0票数 0

我使用React和样式组件创建了简单的accordion。我有一个问题,使效果,使较低的部分可以慢慢滑出,而不是立即弹出。我使用了一个过渡,但我不知道为什么它在我的情况下不起作用。下面是我的部分代码:https://codesandbox.io/s/sweet-blackwell-v78wt?file=/src/App.js

EN

回答 1

Stack Overflow用户

发布于 2020-10-06 03:52:38

为了获得最佳效果,您需要将max-height0px转换为内容高度,反之亦然。您将需要使用useRefuseEffect挂钩来选择元素并手动设置元素上的样式。

您还需要一个知道内容高度的内部包装器。这将是在折叠容器上设置max-height的参考。

使用onTransitionEnd事件侦听器,可以在展开折叠面板时移除max-height属性。这使元素能够根据内容相应地调整大小。

内容的高度由getBoundingClientRect()函数决定。它返回一个具有元素高度、宽度(以及更多)的对象。这样,您就可以确定内容容器的高度。

下面的示例是一个基于您的代码的可行示例。

代码语言:javascript
复制
import React, { useState, useRef, useEffect } from "react";
import "./styles.css";
import styled from "styled-components";

const Accordion = () => {
  const [isExpanded, setIsExpanded] = useState(false);
  const [isAnimating, setIsAnimating] = useState(false);
  const collapseRef = useRef(null);
  const contentRef = useRef(null);

  const handleClick = () => {
    /**
     * isAnimating prevents the accordion from changing
     * state when it is in the middle of a transition.
     */
    if (!isAnimating) {
      setIsAnimating(true);
      setIsExpanded((isExpanded) => !isExpanded);
    }
  };

  const handleTransition = () => {
    if (isExpanded) {
      /**
       * Removing the max-height when expanded makes sure
       * that the element still resizes responsively correct.
       */
      collapseRef.current.style.maxHeight = "";
    }
    setIsAnimating(false);
  };

  useEffect(() => {
    const { height } = contentRef.current.getBoundingClientRect();
    collapseRef.current.style.maxHeight = `${height}px`;
    if (!isExpanded) {
      /**
       * This makes sure that the element first is expanded
       * and in the next frame paint is transitioned to 0px.
       * Otherwise the 0px height would overwrite to dynamic height
       * and there'd be no transition.
       */
      requestAnimationFrame(() => {
        collapseRef.current.style.maxHeight = "0px";
      });
    }
  }, [isExpanded]);

  return (
    <ContentWrapper onClick={handleClick}>
      <TitleCard>
        <h2>Example text</h2>
      </TitleCard>
      <DescriptionCard
        ref={collapseRef}
        isVisible={isExpanded}
        style={{ maxHeight: "0px" }}
        onTransitionEnd={handleTransition}
      >
        <DescriptionContent ref={contentRef}>
          <p>Example text 2</p>
          <p>Now it expands based on the height of the</p>
          <h3>content.</h3>
          <p>Now it expands based on the height of the</p>
          <h3>content.</h3>
        </DescriptionContent>
      </DescriptionCard>
    </ContentWrapper>
  );
};

export default function App() {
  return (
    <div className="App">
      <Accordion />
    </div>
  );
}

const DescriptionContent = styled.div`
  display: flex;
  flex-direction: column;
`;

const DescriptionCard = styled.div`
  background: grey;
  overflow: hidden;
  align-items: center;
  justify-content: flex-start;
  transition: max-height 0.35s;
`;

const TitleCard = styled.div`
  cursor: pointer;
  height: 4.8rem;
  background: #ffffff;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 1.5em;
`;

const ContentWrapper = styled.div`
  border-radius: 16px;
  border: 2px solid black;
  overflow: hidden;
`;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64214329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档