具有最大动态高度的CSS动画元素

时间:2020-10-03 11:52:23

标签: javascript css ionic-framework

我浏览了很多帖子,它们与我需要的内容相似,但不完全相同,而且似乎有很多人希望为max-height: auto制作动画,这不是我所需要的。 这是我所拥有的照片: enter image description here

列表1仅1个元素长,并带有一个“子列表”。列表2当前包含2个元素,但是它是动态生成的,因此将来会有更多。为了避免在展开列表1时将列表2推离屏幕,我需要这样设置最大高度:

let e = document.getElementsByClassName("sub-list-container")[0] as HTMLElement;
let e1 = document.getElementsByClassName("secondary-list")[0] as HTMLElement;

e.style.maxHeight = "calc(100% - " + e1.getBoundingClientRect().height + "px)"

我无法在CSS中设置此值,因为列表2的高度发生了变化,所以我不能仅对值进行硬编码。

对于下拉列表的动画,我最初使用的是translateY

.sub-list.slide-in {
    animation-name: slide-in;
    animation-duration: 0.6s;
    animation-fill-mode: forwards;
}
@keyframes slide-in {
    from {
        transform: translateY(-100%);
    }
    to {
        transform: translateY(0);
    }
}

,并使用classList.add播放动画。 问题是,尽管这会对列表的内容产生滑动效果,但列表1的实际高度会立即设置为满,因此会将列表2推到底部而又不会滑落。 我认为获得这种效果的唯一方法是为max-height设置动画。为此,我需要将其从max-height 0设置为上面显示的动态高度的动画。它必须是max-height: calc(100% - Ypx);,其中Y是列表2的高度。当然,您不能访问css中的属性,因此必须像上面的JS中那样进行操作,但是由于它在关键帧中,对此进行编辑也非常困难。 一种获取我发现(然后更改它)的关键帧的方法是这样的:

getRule() {
    var rule;
    var ss = document.styleSheets;
    for (var i = 0; i < ss.length; ++i) {
        for (var x = 0; x < ss[i].cssRules.length; ++x) {
            rule = ss[i].cssRules[x];
            if (rule.name == "slide-in" && rule.type === CSSRule.KEYFRAMES_RULE) {
                return rule;
            }
        }
    }
}

但这不仅可能是不好的做法,而且对我来说也是错误的:

Property 'cssRules' does not exist on type 'StyleSheet'.  TS2339

即使它可行,获得规则后,您也需要对其进行编辑,然后将其重新添加到样式表中,这相当慢。

这是实际的JSX:

<IonList class="sub-list-container">
    <IonListHeader class="item list-header" lines="full">
        <IonLabel>Menu</IonLabel>
        <div className="ver-text">Version 1.0.0</div>
    </IonListHeader>
    {
        this.pages.map(p => {
            if (p.children?.length > 0) {
                return (
                    <>
                        <IonItem onClick={() => { this.update(p) }} class="item" style={{ "zIndex": "2" }} lines={p.open ? "none" : "inset"}>
                            {p.open ? <IonIcon slot="start" icon={chevronDownOutline} class="icons"></IonIcon> : <IonIcon slot="start" icon={chevronForwardOutline} class="icons"></IonIcon>}
                            <IonLabel>{p.title}</IonLabel>
                        </IonItem>

                        <IonList class="sub-list">
                            {p.open ? <IonMenuToggle autoHide={false} key={p.title}>
                                <IonItem></IonItem>
                                {
                                    p.children.map(el => el)
                                }
                            </IonMenuToggle> : ""}
                        </IonList>
                    </>
                );
            }
        })
    }
</IonList>
<IonList class="secondary-list">
    {
        this.pages.map(p => {
            if (p.children?.length === undefined) {
                return (
                    <IonMenuToggle autoHide={p.autoHide} key={p.title}>
                        <IonItem routerDirection="forward" routerLink={p.url} class="item">
                            <IonIcon slot="start" icon={p.icon}></IonIcon>
                            <IonLabel>{p.title}</IonLabel>
                        </IonItem>
                    </IonMenuToggle>
                )
            }
        })
    }
</IonList>

我想让sub-list向下移动(更改其高度),同时也向下推secondary-list

我还尝试了对scaleY进行动画处理,但效果不错。 我只尝试了height,但这是不可能的。如果有人可以帮忙,将不胜感激

0 个答案:

没有答案
相关问题