html - 为弹性列中的滑动效果转换哪个属性
问题描述
我有一个驻留在容器中的列表,该列表将定期从容器底部删除/添加项目。容器本身固定在视口的左下方。
当添加一个新孩子时,我希望所有现有的孩子向上滑动,当一个孩子被移除时,它上面的所有兄弟姐妹都向下滑动。
我不知道要transition
为列表元素打开哪个属性。当我正确应用它时,当一个孩子被附加时transition: all ...;
,.toast
它会向上滑动 - 但不是当一个孩子被移除时。
显然,因为transition: all
有效,该属性可以动画,但我无法弄清楚它是哪个属性。我已经尝试过transition: bottom
, height
,margin-bottom
和其他几个 - 但他们没有达到我想要的。我希望避免使用transition: all
并希望transition
仅适用于必要的属性。
编辑要明确:我不是在询问动画单个 toast 进入/退出动画(即正在添加/删除的动画),而是如何控制已经存在的其他toast 的移动并重新流动以便制作添加/填写删除的空间。
这是代码的粗略草图。
let counter = 3;
let toasterEl = document.getElementById("toaster");
const newToast = () => toasterEl.insertAdjacentHTML('beforeend',`<div class="toast">${++counter}</div>`);
const removeToast = () => toasterEl.removeChild(toasterEl.childNodes[toasterEl.childNodes.length - 1])
#toaster {
position: fixed;
left: 0;
bottom: 0;
flex-direction: column;
max-width: 100px;
min-height: 100px;
}
.toast {
transform-origin: center bottom;
transition: ??? .5s linear;
animation: toast-entry .5s ease-in;
background-color: tan;
color: black;
padding: 10px;
margin: 10px;
width: 100%;
text-align: center;
}
@keyframes toast-entry {
0% {
transform: rotateX(90deg);
opacity: 0.5;
}
50% {
transform: rotateX(0deg);
opacity: 1;
}
}
<button onclick="newToast()">Make toast</button>
<button onclick="removeToast()">Burn toast</button>
<div id="toaster">
<div class="toast">1</div>
<div class="toast">2</div>
<div class="toast">3</div>
</div>
解决方案
我宁愿说达到预期效果的最佳方法是在过渡完成后侦听transitionend
这些元素和该元素上的事件。.remove()
这是一个工作示例:
let counter = 3;
let toasterEl = document.getElementById("toaster");
const newToast = () => toasterEl.insertAdjacentHTML('beforeend',`<div class="toast">${++counter}</div>`);
const removeToast = () => {
var child = toasterEl.childNodes[ toasterEl.childNodes.length - 1 ];
child.style.height = child.offsetHeight + 'px';
child.addEventListener( 'transitionend', function( e ) {
this.remove();
});
// this is a trick to let browser paint set `offsetHeight` first then start transition from that value to zero
setTimeout( function() {
child.style.height = child.style.paddingTop = child.style.paddingBottom = child.style.marginTop = child.style.marginBottom = 0;
}, 10 );
}
#toaster {
position: fixed;
left: 0;
bottom: 0;
flex-direction: column;
max-width: 200px;
min-height: 200px;
}
.toast {
transform-origin: center top;
overflow: hidden;
transition: height .3s ease-out, margin .3s ease-out, padding .3s ease-out;
animation: toast-entry .5s ease-in;
background-color: tan;
color: black;
padding: 20px;
margin: 10px;
width: 100%;
box-sizing: border-box;
text-align: center;
}
@keyframes toast-entry {
0% {
transform: rotateX(90deg);
opacity: 0.5;
}
50% {
transform: rotateX(0deg);
opacity: 1;
}
}
<button onclick="newToast()">Make toast</button>
<button onclick="removeToast()">Burn toast</button>
<div id="toaster">
<div class="toast">1</div>
<div class="toast">2</div>
<div class="toast">3</div>
</div>
值得一提:
- 您需要
transition
在其他两个padding
和margin
属性上使用以及它height
本身。 - 为了简单起见,我已更改
box-sizing
为border-box
. - 如果您决定使用这种方法,最好也使用其他前缀事件名称
transitionend
。 e.propertyName
如果您想选择何时删除元素,则事件函数中有一个属性可供使用。
推荐阅读
- linux - bash中不同脚本的不同功能
- android - 在 AsyncTask InputStream 中得到 android.os.NetworkOnMainThreadException
- android - Android 应用内更新返回缓存的应用更新信息
- c# - 如何刷新 Google OAuth2 AccessToken
- php - 存储查询结果以供以后在会话或临时表中使用或一一查询?
- ibm-mobilefirst - JSON 日期属性在存储到 JSONStore 后被解析为本地时区
- android - 如何更新当前不在屏幕上焦点的回收器视图的特定位置的视图?
- informix - Informix 今日运算符
- scala - 什么(确切地说)是“头等舱”模块?
- r - 动态替换字符串中的特定字符并将它们分配给新变量