自身警报执行两次



我有一个小类,可以用来生成和显示警报。警报的持续时间和内容通过类函数提供给类并进行控制。

当我触发toast时,它会在durationTime之后再次正确显示和隐藏。但随后警报再次出现,不久后又被隐藏起来。在代码的任何部分,我都不会调用警报两次。

问题:我想这可能与上下文和时间集有关。但我对此没有什么经验。有人能帮帮我吗?提前感谢!最大

class ToastHawaii {
constructor(config = {}) {
this.duration = typeof(config.duration) == 'undefined' ? 1000 : config.duration;
this.toastContainer = config.toastContainer;
}
makeToast(d) {
const html = `<div class="toast">
<div>${d.title}</div>
<div class="right">${d.content}</div>
</div>`;
this.toastContainer.innerHTML = html;
this.toastContainer.classList.add("show");
setTimeout(() => { 
this.toastContainer.classList.remove("show");
}, this.duration);
}
}
const mA = new ToastHawaii({
duration: 4000,
toastContainer: document.querySelector('#myAlertContainer')
});
const content = `ICON`;
document.querySelector("button").addEventListener('click', () => {
mA.makeToast({
title: "hello", 
content: content 
});  
})
#myAlertContainer {
position: fixed;
left: 0%;
top: 30px;  
visibility: hidden;
width:100%;
z-index: 1;
height:60px;
}
.toast {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 8px;
background: gray;
color: #000;
height:100%;
padding: 0 16px;
font-size: 0.8rem;
font-weight: bold;
margin: 0 auto;
max-width: 350px;
}
.right {
display: flex;
gap: 5px;
align-items: center;
}
#myAlertContainer.show {
visibility: visible;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
}
@-webkit-keyframes fadein {
from {top: 0; opacity: 0;} 
to {top: 30px; opacity: 1;}
}
@keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 30px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {top: 30px; opacity: 1;} 
to {top: 0; opacity: 0;}
}
@keyframes fadeout {
from {top: 30px; opacity: 1;}
to {top: 0; opacity: 0;}
}
<div id="myAlertContainer"></div>
<button>makeAlert!</button>
<h1>hello</h1>
<p>lorem ipsum</p>

发生这种情况是因为您的超时时间是4s,但淡出动画是3s。根据您的CSS动画持续时间调整您的超时将修复它。

class ToastHawaii {
constructor(config = {}) {
this.duration = typeof(config.duration) == 'undefined' ? 1000 : config.duration;
this.toastContainer = config.toastContainer;
}
makeToast(d) {
const html = `<div class="toast">
<div>${d.title}</div>
<div class="right">${d.content}</div>
</div>`;
this.toastContainer.innerHTML = html;
this.toastContainer.classList.add("show");
setTimeout(() => { 
this.toastContainer.classList.remove("show");
}, this.duration);
}
}
const mA = new ToastHawaii({
duration: 3000,
toastContainer: document.querySelector('#myAlertContainer')
});
const content = `ICON`;
document.querySelector("button").addEventListener('click', () => {
mA.makeToast({
title: "hello", 
content: content 
});  
})
#myAlertContainer {
position: fixed;
left: 0%;
top: 30px;  
visibility: hidden;
width:100%;
z-index: 1;
height:60px;
}
.toast {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 8px;
background: gray;
color: #000;
height:100%;
padding: 0 16px;
font-size: 0.8rem;
font-weight: bold;
margin: 0 auto;
max-width: 350px;
}
.right {
display: flex;
gap: 5px;
align-items: center;
}
#myAlertContainer.show {
visibility: visible;
animation: fadein 0.5s, fadeout 0.5s 2.5s;
animation-fill-mode: forwards;
}
@-webkit-keyframes fadein {
from {top: 0; opacity: 0;} 
to {top: 30px; opacity: 1;}
}
@keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 30px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {top: 30px; opacity: 1;} 
to {top: 0; opacity: 0;}
}
@keyframes fadeout {
from {top: 30px; opacity: 1;}
to {top: 0; opacity: 0;}
}
<div id="myAlertContainer"></div>
<button>makeAlert!</button>
<h1>hello</h1>
<p>lorem ipsum</p>

HTMHell的回答解释了问题所在,并展示了一种修复方法,但该解决方案的问题是,您的JavaScript代码不再负责警报显示的时间。

另一种方法是使用transition而不是animation;直到类被删除,才开始转换回不可见状态(请参阅CSS中的标记注释(:

class ToastHawaii {
constructor(config = {}) {
this.duration = typeof(config.duration) == 'undefined' ? 1000 : config.duration;
this.toastContainer = config.toastContainer;
}
makeToast(d) {
const html = `<div class="toast">
<div>${d.title}</div>
<div class="right">${d.content}</div>
</div>`;
this.toastContainer.innerHTML = html;
this.toastContainer.classList.add("show");
setTimeout(() => { 
this.toastContainer.classList.remove("show");
}, this.duration);
}
}
const mA = new ToastHawaii({
duration: 4000,
toastContainer: document.querySelector('#myAlertContainer')
});
const content = `ICON`;
document.querySelector("button").addEventListener('click', () => {
mA.makeToast({
title: "hello", 
content: content 
});  
})
#myAlertContainer {
position: fixed;
left: 0;
top: 0;
opacity: 0;                        /* <=== */
width:100%;
height:60px;
z-index: -1;                       /* <=== */
transition: top 0.5s, opacity 0.5s /* <=== */
}
#myAlertContainer.show {
z-index: 1;                        /* <=== */
top: 30px;                         /* <=== */
opacity: 1;                        /* <=== */
}
.toast {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 8px;
background: gray;
color: #000;
height:100%;
padding: 0 16px;
font-size: 0.8rem;
font-weight: bold;
margin: 0 auto;
max-width: 350px;
}
.right {
display: flex;
gap: 5px;
align-items: center;
}
<div id="myAlertContainer"></div>
<button>makeAlert!</button>
<h1>hello</h1>
<p>lorem ipsum</p>

这样,无论代码将元素保留多长时间,它总是需要半秒钟才能出现,然后半秒钟才能消失。(如果你想将延迟计算为"持续时间"控件的一部分,你可以在删除类之前从延迟中减去该时间。(

如果希望消失与出现所花费的时间不同,可以在#myAlertContainer.show规则中放入不同的transition。那将控制外观,#myAlertContainer规则中的那个将控制消失。这是一个非常缓慢的消失:

class ToastHawaii {
constructor(config = {}) {
this.duration = typeof(config.duration) == 'undefined' ? 1000 : config.duration;
this.toastContainer = config.toastContainer;
}
makeToast(d) {
const html = `<div class="toast">
<div>${d.title}</div>
<div class="right">${d.content}</div>
</div>`;
this.toastContainer.innerHTML = html;
this.toastContainer.classList.add("show");
setTimeout(() => { 
this.toastContainer.classList.remove("show");
}, this.duration);
}
}
const mA = new ToastHawaii({
duration: 4000,
toastContainer: document.querySelector('#myAlertContainer')
});
const content = `ICON`;
document.querySelector("button").addEventListener('click', () => {
mA.makeToast({
title: "hello", 
content: content 
});  
})
#myAlertContainer {
position: fixed;
left: 0;
top: 0;
opacity: 0;                        /* <=== */
width:100%;
height:60px;
z-index: -1;                       /* <=== */
transition: top 2.5s, opacity 2.5s /* <=== */
}
#myAlertContainer.show {
z-index: 1;                        /* <=== */
top: 30px;                         /* <=== */
opacity: 1;                        /* <=== */
}
.toast {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 8px;
background: gray;
color: #000;
height:100%;
padding: 0 16px;
font-size: 0.8rem;
font-weight: bold;
margin: 0 auto;
max-width: 350px;
}
.right {
display: flex;
gap: 5px;
align-items: center;
}
<div id="myAlertContainer"></div>
<button>makeAlert!</button>
<h1>hello</h1>
<p>lorem ipsum</p>

问题出在动画持续时间上。你的淡出动画持续时间是2.5秒,并且你在4000毫秒后从你的设置中删除了表演类。这就是它们相互冲突的原因。我改变了你的动画持续时间,它解决了。

class ToastHawaii {
constructor(config = {}) {
this.duration = typeof(config.duration) == 'undefined' ? 1000 : config.duration;
this.toastContainer = config.toastContainer;
}
makeToast(d) {
const html = `<div class="toast">
<div>${d.title}</div>
<div class="right">${d.content}</div>
</div>`;
this.toastContainer.innerHTML = html;
this.toastContainer.classList.add("show");
setTimeout(() => { 
this.toastContainer.classList.remove("show");
}, this.duration);
}
}
const mA = new ToastHawaii({
duration: 4000,
toastContainer: document.querySelector('#myAlertContainer')
});
const content = `ICON`;
document.querySelector("button").addEventListener('click', () => {
mA.makeToast({
title: "hello", 
content: content 
});  
})
#myAlertContainer {
position: fixed;
left: 0%;
top: 30px;  
visibility: hidden;
width:100%;
z-index: 1;
height:60px;
}
.toast {
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 8px;
background: gray;
color: #000;
height:100%;
padding: 0 16px;
font-size: 0.8rem;
font-weight: bold;
margin: 0 auto;
max-width: 350px;
}
.right {
display: flex;
gap: 5px;
align-items: center;
}
#myAlertContainer.show {
visibility: visible;
animation: fadein 0.5s, fadeout 0.5s 3.6s;
}
@-webkit-keyframes fadein {
from {top: 0; opacity: 0;} 
to {top: 30px; opacity: 1;}
}
@keyframes fadein {
from {top: 0; opacity: 0;}
to {top: 30px; opacity: 1;}
}
@-webkit-keyframes fadeout {
from {top: 30px; opacity: 1;} 
to {top: 0; opacity: 0;}
}
@keyframes fadeout {
from {top: 30px; opacity: 1;}
to {top: 0; opacity: 0;}
}
<div id="myAlertContainer"></div>
<button>makeAlert!</button>
<h1>hello</h1>
<p>lorem ipsum</p>

最新更新