I’m implementing a toast notification function in JavaScript. The code is very simple, so it’s self-explanatory:
HTML
<div id="notifications"></div>
JS
const notify = (type, text, autohide = true) => {
const box = `<div class="notification ${type}">${text}<span onclick="notifyHide(parentNode)"></span></div>`;
notifications.insertAdjacentHTML("afterbegin", box);
if (autohide) setTimeout(() => {
notifyHide(box);
}, 5000);
};
const notifyHide = el => {
el.classList.add("hide");
setTimeout(() => {
el.remove();
}, 500);
};
THE ISSUE
When “autohide” is false, there’s no problem: clicking on “X”, the div element disappears (thanks to the added class “hide”), then is removed from the DOM.
Instead, when “autohide” is true, I get the following error: “Uncaught TypeError: el.classList is undefined”.
What’s the reason of that error?
const notify = (type, text, autohide = true) => {
const box = `<div class="notification ${type}">${text}<span onclick="notifyHide(parentNode)"></span></div>`;
notifications.insertAdjacentHTML("afterbegin", box);
if (autohide) setTimeout(() => {
notifyHide(box);
}, 5000);
};
const notifyHide = el => {
el.classList.add("hide");
setTimeout(() => {
el.remove();
}, 500);
};
notify("success", "This works", false);
notify("error", "This doesn't work");
#notifications {
bottom: 20px;
max-width: calc(100% - 30px);
position: fixed;
right: 20px;
width: 500px;
}
.notification {
align-items: center;
animation: grow 0.5s ease-in forwards;
background-color: var(--bc);
border-radius: 3px;
box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, .75);
color: white;
display: flex;
font-size: 18px;
justify-content: space-between;
margin-top: 15px;
padding: 15px;
text-align: left;
}
.notification span {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAYAAAA7bUf6AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABCklEQVQ4jYWTsYrDMBBEtzLG1XEYE/L/jbkqGJMimFRHOFKFVPmKI1w/L0WsnCxp4wUVlpan8c7IzMyATtIJ6CVV9qaACuiBb6ANmx1w5b8GoHYANTBGvVegNeCHvEZJC5CkGtgXek8231yqMSiaFZQAADsDGmCSRGGNkj4k7cMeEJ8fXoqBRtLRAf3G3xFkAhpL/rkBPFAKmSQtAdH0X4rCjYl8gFxBWpJaSXdniHfg8y1gxYXMtZKCOnZhZWU5WgP8rYJ4voXRkT5J6oCjcz5Iqgz48gDBBZ6B9EC9SToXpGY5YLYfSHvPBmyAW5SJA04OSJ4IcAM2YbBb4ALsXPuWoEHSBdiamT0AyQw4IRLJeTkAAAAASUVORK5CYII=);
cursor: pointer;
height: 17px;
margin-left: 20px;
width: 17px;
}
.notification.success {
--bc: #55B559;
}
.notification.error {
--bc: #EA4333;
}
.notification.hide {
animation: shrink 0.3s ease-out forwards;
pointer-events: none;
}
@keyframes grow {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes shrink {
to {
opacity: 0;
transform: scale(0.8);
}
}
<div id="notifications"></div>