Home > database >  Why removeChild method doesn't remove element?
Why removeChild method doesn't remove element?

Time:12-20

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);
  • Related