From 41b04a12cfde748ff38a37afa1ca16d93716349f Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Sun, 27 Oct 2024 23:56:47 +0100 Subject: [PATCH] 116404: Fixe event listeners not properly being cleaned --- .../expandable-navbar-section.component.ts | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts index 8951c02c103..b28aa258048 100644 --- a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts +++ b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts @@ -72,6 +72,11 @@ export class ExpandableNavbarSectionComponent extends NavbarSectionComponent imp */ addArrowEventListeners = false; + /** + * List of current dropdown items who have event listeners + */ + private dropdownItems: NodeListOf; + @HostListener('window:resize', ['$event']) onResize() { this.isMobile$.pipe( @@ -101,18 +106,20 @@ export class ExpandableNavbarSectionComponent extends NavbarSectionComponent imp this.subs.push(this.active$.subscribe((active: boolean) => { if (active === true) { this.addArrowEventListeners = true; + } else { + this.unsubscribeFromEventListeners(); } })); } ngAfterViewChecked(): void { if (this.addArrowEventListeners) { - const dropdownItems: NodeListOf = document.querySelectorAll(`#${this.expandableNavbarSectionId()} *[role="menuitem"]`); - dropdownItems.forEach((item: HTMLElement) => { + this.dropdownItems = document.querySelectorAll(`#${this.expandableNavbarSectionId()} *[role="menuitem"]`); + this.dropdownItems.forEach((item: HTMLElement) => { item.addEventListener('keydown', this.navigateDropdown.bind(this)); }); - if (dropdownItems.length > 0) { - dropdownItems.item(0).focus(); + if (this.dropdownItems.length > 0) { + this.dropdownItems.item(0).focus(); } this.addArrowEventListeners = false; } @@ -120,10 +127,20 @@ export class ExpandableNavbarSectionComponent extends NavbarSectionComponent imp ngOnDestroy(): void { super.ngOnDestroy(); - const dropdownItems: NodeListOf = document.querySelectorAll(`#${this.expandableNavbarSectionId()} *[role="menuitem"]`); - dropdownItems.forEach((item: HTMLElement) => { - item.removeEventListener('keydown', this.navigateDropdown.bind(this)); - }); + this.unsubscribeFromEventListeners(); + } + + /** + * Removes all the current event listeners on the dropdown items (called when the menu is closed & on component + * destruction) + */ + unsubscribeFromEventListeners(): void { + if (this.dropdownItems) { + this.dropdownItems.forEach((item: HTMLElement) => { + item.removeEventListener('keydown', this.navigateDropdown.bind(this)); + }); + this.dropdownItems = undefined; + } } /**