我浏览了很多帖子,它们与我需要的内容相似,但不完全相同,而且似乎有很多人希望为max-height: auto
制作动画,这不是我所需要的。
这是我所拥有的照片:
列表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
,但这是不可能的。如果有人可以帮忙,将不胜感激