我有以下示例代码,它创建从屏幕顶部飞出的吐司,停留几秒钟,然后飞走:
function createToast() {
const elem = document.createElement("div");
elem.classList.add("toast");
elem.innerText = "hello";
document.body.appendChild(elem);
setTimeout(() => elem.remove(), 3000);
}
setInterval(createToast, 3000);
body {
background-color: #d7d7d7;
}
.toast {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
max-width: 200px;
transform: translate(0, 0);
background-color: #fff;
border-radius: 50px;
animation-name: toastin, toastout;
animation-duration: 0.3s, 0.5s;
animation-iteration-count: 1, 1;
animation-delay: 0s, 2.5s;
animation-fill-mode: forwards, forwards;
}
@keyframes toastin {
from {
opacity: 0;
transform: translate(0, -40px);
}
to {
opacity: 1;
transform: translate(0, 20px);
}
}
@keyframes toastout {
from {
opacity: 1;
transform: translate(0, 20px);
}
to {
opacity: 0;
transform: translate(50vw, 20px);
}
}
<body><body>
这很好用,但有时在我的应用程序中,会在当前的 toast 消失之前创建另一个 toast。在那种情况下,我希望当前的吐司在新吐司创建后立即飞走,而不是等待 2.5 秒。
对于我的生活,我无法弄清楚这一点。是否可以?看起来很简单,但我尝试的任何东西似乎都没有任何效果。
首先,我尝试抓住现有的 toast 元素并将
animation-delay
设置为 0s
,但这没有效果。然后我尝试用一个全新的动画替换它,尝试使用!important
等。在所有情况下,吐司就像消失一样,没有动画发生。
有没有办法让 toast 在创建新 toast 时立即在 0.4 秒内完成其当前动画?以便它在与传入的吐司碰撞之前飞走?
你会认为这是可能的,对吧?也许您需要添加一个变量来检查是否显示了吐司。如果正在显示 toast,您可以立即应用 elem.remove() 以仅显示新的 toast。在下面查看是否适合您。
let isToastDisplayed = false;
function createToast() {
const elem = document.createElement("div");
elem.classList.add("toast");
elem.innerText = "hello";
document.body.appendChild(elem);
if (isToastDisplayed) {
const currentToast = document.querySelector(".toast");
currentToast.remove();
}
isToastDisplayed = true;
setTimeout(() => {
elem.remove();
isToastDisplayed = false;
}, 3000);
}
setInterval(createToast, 3000);
body {
background-color: #d7d7d7;
}
.toast {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
max-width: 200px;
transform: translate(0, 0);
background-color: #fff;
border-radius: 50px;
animation-name: toastin, toastout;
animation-duration: 0.3s, 0.5s;
animation-iteration-count: 1, 1;
animation-delay: 0s, 2.5s;
animation-fill-mode: forwards, forwards;
}
@keyframes toastin {
from {
opacity: 0;
transform: translate(0, -40px);
}
to {
opacity: 1;
transform: translate(0, 20px);
}
}
@keyframes toastout {
from {
opacity: 1;
transform: translate(0, 20px);
}
to {
opacity: 0;
transform: translate(50vw, 20px);
}
}
<body><body>
不确定这是否直接回答了你的问题,但你可以将动画分离到一个单独的类中......然后使用 js 你可以检查现有的动画并添加类!
检查一下
function createToast() {
const existing = document.querySelectorAll('.toast')
if(existing.length > 0) {
existing.forEach(e => {
e.classList.add('toast-out')
})
}
const elem = document.createElement("div");
elem.classList.add("toast");
elem.innerText = "hello";
document.body.appendChild(elem);
setTimeout(() => elem.remove(), 3000);
}
setInterval(createToast, 2000);
body {
background-color: #d7d7d7;
}
.toast {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
max-width: 200px;
transform: translate(0, 0);
background-color: #fff;
border-radius: 50px;
animation-name: toastin;
animation-duration: 0.3s;
animation-iteration-count: 1;
animation-delay: 0s;
animation-fill-mode: forwards;
}
.toast-out {
animation-name: toastout;
animation-duration: 0.5s;
animation-iteration-count: 1;
animation-delay: 0s;
animation-fill-mode: forwards;
}
@keyframes toastin {
from {
opacity: 0;
transform: translate(0, -40px);
}
to {
opacity: 1;
transform: translate(0, 20px);
}
}
@keyframes toastout {
from {
opacity: 1;
transform: translate(0, 20px);
}
to {
opacity: 0;
transform: translate(50vw, 20px);
}
}
<body><body>
您需要保留对 elem 的引用,并在再次调用该函数时将其删除。也许是这样的:
let activeToast;
function clearToast() {
if(!activeToast){
return;
}
activeToast.remove();
activeToast = null;
}
function createToast() {
clearToast();
const elem = document.createElement("div");
elem.classList.add("toast");
elem.innerText = "hello";
activeToast = elem;
document.body.appendChild(elem);
setTimeout(() => clearToast(), 3000);
}
setInterval(createToast, 3000);
但是如果您想跟踪动画,则可能需要使用一些动画事件。
https://medium.com/front-end-weekly/css-animation-events-in-javascript-d2bfe702636d