I have realized toast notifications by using vanilla javascript. Code works great, but one problem, why this code below doesn't work? What i should replace or add or remove? I don't understand why it doesn't work, could somebody explain me?
const autoRemove = setTimeout(function () {
item.removeChild(toast);
}, duration 1000);
Here is code snippet of full application:
function toast({title = '', description = '', type = message, duration = 5000}) {
const item = document.querySelector('#toast');
if(item) {
const toast = document.createElement('div');
const autoRemove = setTimeout(function () {
item.removeChild(toast);
}, duration 1000);
toast.addEventListener('click', function(event) {
if (event.target.closest('.close')) {
item.removeChild(toast);
clearTimeout(autoRemove);
}
});
const delay = (duration / 1000).toFixed(2);
toast.classList.add('toast', `${type}`);
toast.style.animation = `slide ease 1s, out ease 1s ${delay}s forwards`;
toast.innerHTML = `
<div>
<span >${title}</span>
<i ></i>
</div>
<p >${description}</p>`;
item.appendChild(toast);
}
}
const button = document.querySelector('.button');
button.addEventListener('click', function() {
toast ({
title: 'Lorem ipsum',
description: 'Lorem ipsum dolor sit amet',
type: 'message',
duration: '5000'
});
});
body {
font-family: Arial, Helvetica, sans-serif;
min-height: 100vh;
}
.container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
justify-content: center;
align-items: center;
}
*,
*:before,
*:after
{
box-sizing: border-box;
margin: 0;
padding: 0;
}
.button
{
cursor: pointer;
border: none;
text-transform: uppercase;
white-space: nowrap;
color: #fff;
background-color: #21262b;
border-radius: 5px;
padding: 10px;
font-size: 14px;
font-weight: bold;
}
@media(max-width: 992px) {
.container {
flex-direction: column;
}
}
#toast {
position: fixed;
top: 25px;
right: 25px;
z-index: 100;
}
.toast {
background: #fff;
box-shadow: rgba(100, 100, 110, 0.25) 0px 5px 30px 0px;
padding: 20px;
width: 250px;
border-radius: 7.5px;
border-left: 5px solid;
transition: all ease 0.25s;
}
.toast div {
display: flex;
justify-content: space-between;
}
.toast .toast {
margin-top: 20px;
}
.toast.message {
border-color: #21262b;
}
.toast.message .title {
color: #21262b;
}
.toast.message .close {
color: #21262b;
}
.toast.success {
border-color: #20bdff;
}
.toast.success .title {
color: #20bdff;
}
.toast.success .close{
color: #20bdff;
}
.toast.error {
border-color: #f85032;
}
.toast.error .title {
color: #f85032;
}
.toast.error .close{
color: #f85032;
}
@keyframes slide {
from {
opacity: 0;
transform: translate(calc(100% 25px), 0);
}
to {
opacity: 1;
transform: translate(0);
}
}
@keyframes out {
from {
opacity: 1;
transform: translate(0);
}
to {
opacity: 0;
transform: translate(calc(100% 25px), 0);
}
}
.title {
font-weight: bold;
font-size: 20px;
}
.description {
margin-top: 10px;
font-size: 12px;
}
.close {
font-size: 20px;
cursor: pointer;
}
<div >
<button >Toast Button</button>
</div>
<div id="toast"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/js/all.min.js"></script>
CodePudding user response:
When you create a toast (in the example) you pass duration: '5000'
. In toast()
you then use a delay of duration 1000
which results in '50001000'
, not the intended 6000
.
You can either pass the duration as a number or parse the string as a number and only then add 1000
.
button.addEventListener('click', function() {
toast ({
title: 'Lorem ipsum',
description: 'Lorem ipsum dolor sit amet',
type: 'message',
duration: 5000
});
});
or
const autoRemove = setTimeout(function () {
item.removeChild(toast);
}, Number(duration) 1000);