el.parentNode возвращает null в setTimeout
Есть система, отображающая уведомления на клиенте.
Уведомления приходят по websocket и показываются при вызове функции showNotification(), в которой они создаются путем добавления html-кода через innerHTML контейнера.
Для скрытия уведомления на кнопку в уведомлении вешается событие клик и в функцию hideNotification() передается сам элемент, в которой далее уведомление удаляется путем присваивания анимации скрытия через style, а далее, через 500мс, удаляется при помощи el.parentNode.removeChild(el).
function showNotification(thisNotification){
// action: "notification"
// hide: "auto"
// message: "This email is already in use"
// title: "An error occurred"
// type: "error"
let html = '';
switch(thisNotification.type){
case 'error':{
html+=`
<div class="popup-notification popup-notification-error autohide">
<h1 class="notification-title">${thisNotification.title}</h1>
<span class="notification-description description-error">${thisNotification.message}</span>
</div>`
notification_container.innerHTML += html;
let thisAutoHide_element = document.getElementsByClassName('autohide')[0];
setTimeout(() => {
hideNotification(thisAutoHide_element);
}, 5000);
break;
}
case 'friends':{
html+=`
<div class="popup-notification popup-notification-friend">
<h1 class="notification-title">${thisNotification.title}</h1>
<div class="buttons-container">
<button class="notification-button button-confirm friend-request-accept">Accept</button>
<button class="notification-button button-cancel friend-request-reject">Reject</button>
</div>
</div>`
notification_container.innerHTML += html;
const thisNotification_buttonAccept = notification_container.getElementsByClassName('friend-request-accept')[0];
const thisNotification_buttonReject = notification_container.getElementsByClassName('friend-request-reject')[0];
thisNotification_buttonAccept.addEventListener('click', function(){
let from = this.parentNode.parentNode.getElementsByClassName('notification-title')[0].getElementsByClassName('account-notification-link')[0].getAttribute('uid');
let thisNote = this.parentNode.parentNode;
hideNotification(thisNote);
send_friendRequestResponse('accept', from);
})
thisNotification_buttonReject.addEventListener('click', function(){
let from = this.parentNode.parentNode.getElementsByClassName('notification-title')[0].getElementsByClassName('account-notification-link')[0].getAttribute('uid');
send_friendRequestResponse('reject', from);
let thisNote = document.getElementsByClassName('popup-notification-friend')[0];
hideNotification(thisNote);
})
break;
}
case 'alert':{
html+= `
<div class="popup-notification popup-notification-alert">
<h1 class="notification-title">${thisNotification.title}</h1>
<span class="notification-description">${thisNotification.message}</span>
<button class="notification-button button-ok alert-button-ok">OK</button>
</div>
`
notification_container.innerHTML += html;
const buttonOK = document.getElementsByClassName('alert-button-ok');
for(let i = 0; i < buttonOK.length; i++){
buttonOK[i].addEventListener('click', function() {
let thisNote = this.parentNode;
console.log('thisNote = ', thisNote);
hideNotification(thisNote);
})
}
}
}
}
function hideNotification(el){
el.style.animationName = 'notification-hide';
setTimeout(() => {
el.parentNode.removeChild(el);
}, 500);
}
Проблема заключается в том, что любые уведомления, кроме 'friends', удаляются, а при принятии заявки в друзья через уведомление 'friends' - выводится ошибка TypeError: Cannot read properties of null (reading 'removeChild') для строки el.parentNode.removeChild(el);
Ошибка как-то связана с setTimeout, потому что до него parentNode находится:
