簡體   English   中英

"如何使用 ReactCSSTransitionGroup 為 React 中的元素高度設置動畫?"

[英]How to animate element height in React with ReactCSSTransitionGroup?

我正在嘗試使用ReactCSSTransitionGroup<\/code>為元素高度設置動畫,所以這就是我希望動畫的樣子:

http:\/\/jsfiddle.net\/cherrry\/hgk4Lme9\/<\/a>

問題是我並不總是知道元素高度,所以我嘗試在componentDidMount<\/code>期間破解scrollHeight<\/code> 、 clientHeight<\/code>或類似的東西,並嘗試設置node.style.height<\/code>或向樣式表添加規則

http:\/\/jsfiddle.net\/cherrry\/dz8uod7u\/<\/a>

離開動畫看起來不錯,但是當元素進入時,它會閃爍一點,並且縮放動畫看起來很奇怪

應該是因為詢問node.scrollHeight<\/code>導致渲染立即發生,所以無論如何在動畫開始之前獲取相同的信息並注入 css 規則? 還是我應該換個角度思考?

我對max-height<\/code>解決方案不是很滿意,因為當max-height<\/code>不接近或不小於height<\/code>時,生成的動畫速度會非常奇怪,並且我的組件的高度確實變化很大。

我可以想象最終的解決方案可能會有點混亂,但我認為將其制成 Mixin 將足以在任何地方重用它

更多的實驗后,我想出了一個解決方案,通過使用低級別的API ReactTransitionGroup代替高層次ReactCSSTransitionGroup

這是JSFiddle的工作解決方案: http//jsfiddle.net/cherrry/0wgp34cr/

在動畫之前,它正在做三件事:

  1. 獲得計算的高度,填充和邊距
  2. 使用display: none隱藏元素並添加.anim-enter以將height設置為0
  3. .anim-enter-active創建css規則

要開始動畫,它正在做兩件事:

  1. 取消隱藏元素
  2. 添加.anim-enter-active以啟動動畫

JSFiddle中的一些數字和類名是硬編碼的,但它應該很容易將“mixin”轉換為React類,以替代ReactCSSTransitionGroup

我遇到了同樣的問題,最終為動畫高度編寫了一個獨立的組件。

你可以在這里看到演示: https//stanko.github.io/react-animate-height/

它更容易使用,整個庫真的很小(約200行)

<AnimateHeight
  duration={ 500 }
  height={ 'auto' }
>
  <h1>Your content goes here</h1>
  <p>Put as many React or HTML components here.</p>
</AnimateHeight>

對於無恥的自我推銷感到抱歉,但我認為如果您有多個組件可以動畫,它可以為您節省大量時間。

干杯!

如果你不想導入模塊或使用qjuery,這里有一個使用React ref的模板( https://reactjs.org/docs/refs-and-the-dom.html

基本上你得到它的高度,增長到那個高度,切換回自動。 在返回途中切換到它的高度,然后回到0。

class CollapsibleSectionBlock extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        showContent: false,
        height: "0px",
        myRef: null,
    };
}

componentDidUpdate = (prevProps, prevState) => {
    if (prevState.height === "auto" && this.state.height !== "auto") {
        setTimeout(() => this.setState({ height: "0px" }), 1);
    }
}

setInnerRef = (ref) => this.setState({ myRef: ref });

toggleOpenClose = () => this.setState({
    showContent: !this.state.showContent,
    height: this.state.myRef.scrollHeight,
});

updateAfterTransition = () => {
    if (this.state.showContent) {
        this.setState({ height: "auto" });
    }
};

render() {
    const { title, children } = this.props;
    return (
        <div>
            <h2 onClick={() => this.toggleOpenClose()}>
                Example
            </h2>
            <div
                ref={this.setInnerRef}
                onTransitionEnd={() => this.updateAfterTransition()}
                style={{
                    height: this.state.height,
                    overflow: "hidden",
                    transition: "height 250ms linear 0s",
                }}
            >
                {children}
            </div>
        </div>
    );
}

}

一個非常簡單和好的方法是處理 scaleY 而不是 height。 懸停應設置屬性 transform: scaleY(1) (最初 => transform: scaleY(0) 以隱藏它)並且動畫應以 transform 屬性為目標。

"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM