>我有一个应用程序,它从api获取内容并将其显示在flex容器中。使用滑块,我可以浏览此内容。 显示的内容可以有不同的高度,如果我的内容发生变化,我想使用容器高度的平滑动画。由于我要显示的内容是动态的,所以我不能使用容器的固定高度,而是使用 100% 的高度。 有没有办法对高度的变化做出反应并应用例如transistion: height 1s
我也对一些javascript解决方案开放,但请不要提及任何jquery。
请记住,我对 css 很陌生,尤其是对于动画/转换。
这不是一件容易的事,因为transition
动画属性过渡,而如果您通过将元素设置为auto
来动态更改元素的height
(默认情况下它是自动的),它无法将其计算为高度变化,因此没有过渡。只要我知道你最好的选择是事先计算你需要的高度并强制改变它,但如果做不到,我提出了这个非常笨拙的香草解决方案:
const container = document.querySelector('.container');
const data = [
{
lines: 10,
},
{
lines: 25,
},
{
lines: 5,
},
{
lines: 35,
},
{
lines: 15,
},
{
lines: 45,
},
];
const offset = 40;
const asyncData = data.map(
(d, i) => new Promise((res) => setTimeout(() => res(d), 2000 * i))
);
const asyncCycle = async () => {
for (const d of asyncData) {
const res = await d;
const content = Array(res.lines).fill('Hello world').join('');
console.log('BEFORE MUTATION', container.clientHeight);
container.style.height = 'auto';
container.innerHTML = content;
console.log('AFTER MUTATION 1', container.clientHeight);
container.style.height = container.clientHeight - offset + 'px';
}
};
const targetNode = container;
const observerOptions = {
childList: true,
subtree: true,
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, observerOptions);
function callback(mutationList, observer) {
mutationList.forEach((mutation, i) => {
console.log('AFTER MUTATION 2', i, container.clientHeight);
container.style.height = container.clientHeight + 'px';
/* One or more children have been added to and/or removed
from the tree.
(See mutation.addedNodes and mutation.removedNodes.) */
});
}
// START CYCLE
asyncCycle();
body {
display: flex;
justify-content: center;
align-items: center;
}
.container {
width: min(70vw, 300px);
border-radius: 10px;
background: orange;
transition: all 0.2s ease-out;
padding: 10px;
}
<div class="container"></div>
它利用MutationObserver
动态读取容器的新高度,并将其设置为样式属性(可以转换)。不过,这有点缺陷,只是关于如何实现该功能的想法。
只需使用关键帧语句,例如
@keyframes display {
to {
display: 100%;
}
}
然后告诉元素像这样执行动画
#yourElement {
animation-name: display;
animation-duration: 1s;
animation-timing-function: linear;
}
您可以将animation-timing-function: linear
替换为您希望动画外观的任何方式,请参阅 Mozilla 文档。