PageSourceSearch

https://www.interton.com/assets/javascript/Feature/main-navigation/index.js

js interton.com collected 2026-10-01 15:34:19 UTC 6,709 bytes, 179 lines download raw bytes

1import { LanguageSelector } from '../';
2export class MainNavigation {
3    /**
4     * Creates a new instance of the MainNavigation Class
5     * @param {HTMLElement} element MainNavigation DOM Element
6     */
7    constructor(element) {
8        this.element = element;
9
10        this._refs = {
11            el: element,
12            body: document.querySelector('body'),
13            header: document.querySelector('#header'),
14            languageSelector: element.querySelector('.language-selector'),
15            mainList: element.querySelector('.main-navigation__main-list'),
16            ctaList: element.querySelector('.main-navigation__cta-list'),
17            navItems: Array.from(element.querySelectorAll('.main-navigation__item > a')),
18            subNavItems: Array.from(element.querySelectorAll('.main-navigation__menu__sub-item a')),
19            toggl: element.querySelector('.main-navigation__main-menu-toggler')
20        };
21
22        this._props = {
23            visible: false,
24        }
25
26        // Top notice-handling
27        const oTopnotice = this._refs.header.querySelector('.top-notice');
28        if(oTopnotice !== null) {
29            this._refs.header.classList.add('header-top-notice');
30        }
31
32        // Language selector
33        if(this._refs.languageSelector !== null) {
34            this.lang = new LanguageSelector(this._refs.languageSelector);
35        }
36
37        // Event handlings
38        this._refs.navItems.forEach(item => {
39            // WCAG
40            item.addEventListener('keydown', this._onMainNavigationItemKeyDown.bind(this));
41
42            ["click", "keydown"].forEach((event) =>
43              item.addEventListener(event, () =>
44                localStorage.removeItem("scrollposition")
45              )
46            );
47
48            // Caret bindings
49            const oCaret = item.parentElement.querySelector('.main-navigation__caret');
50            if(oCaret !== null) {
51                oCaret.addEventListener('click', this._onMainNavigationItemCaretClick.bind(this));
52            }
53        });
54
55        this._refs.subNavItems.forEach(item => item.addEventListener('keydown', this._onSubNavigationItemKeyDown.bind(this)));
56
57        if(this._refs.toggl !== null) {
58            this._refs.toggl.addEventListener('click', this._onTogglClick.bind(this));
59        }
60    }
61
62    /**
63     * Handler for WCAG implementation on sub-navigational items
64     * @param {Event} e - Event interface
65     */
66    _onSubNavigationItemKeyDown (e = Event) {
67        const
68            oTarget = e.target,
69            oMainMenuItem = oTarget.closest('.main-navigation__item'),
70            oMainMenuItemLink = oMainMenuItem.children[0];
71
72        switch(e.keyCode) {
73            case 27: // ESC
74                oMainMenuItem.classList.remove('is-current-page');
75                oMainMenuItemLink.setAttribute('aria-expanded', 'false');
76
77                this._refs.subNavItems.forEach(item => item.setAttribute('tabindex', '-1'))
78
79                oMainMenuItemLink.focus();
80            break;
81        }
82    }
83
84    /**
85     * Handler for WCAG implementation on main navigational items
86     * @param {Event} e - Event Interface
87     */
88    _onMainNavigationItemKeyDown (e = Event) {
89        const
90            // Classes
91            strItemActiveClass = 'is-current-page',
92            // Elements
93            oTarget = e.target,
94            oParent = oTarget.parentElement,
95            oSubmenuItems = Array.from(oParent.querySelectorAll('.main-navigation__menu__sub-item a')),
96            // States
97            isToggled = oParent.classList.contains(strItemActiveClass);
98
99        switch(e.keyCode) {
100            case 32: // Space
101                // Element has a submenu
102                e.preventDefault();
103
104                // if item has no sub menu, go to page instead
105                if(!oSubmenuItems.length) {
106                    window.location.href = oTarget.getAttribute('href');
107                    return true;
108                }
109
110                // Reset states
111                this._refs.navItems.forEach(x => x.parentElement.classList.remove(strItemActiveClass));
112
113                // Toggle active state
114                if(isToggled) {
115                    oTarget.parentElement.classList.remove(strItemActiveClass);
116                    oTarget.setAttribute('aria-expanded', 'false');
117                    oSubmenuItems.forEach(x => {
118                        x.setAttribute('tabindex', '-1');
119                    });
120                } else {
121                    oTarget.parentElement.classList.add(strItemActiveClass);
122                    oTarget.setAttribute('aria-expanded', 'true');
123
124                    // Set children as tabbable
125                    oSubmenuItems.forEach((x, i) => {
126                        if(i === 0) {
127                            x.focus();
128                        }
129
130                        x.setAttribute('tabindex', '0');
131                    });
132                }
133            break;
134        }
135    }
136
137    /**
138     * Handler for toggling menus on mobile devices
139     * @param {Event} e - Event Interface
140     */
141    _onMainNavigationItemCaretClick (e = Event) {
142        const
143            oElement = e.target,
144            oMainElement = oElement.parentElement,
145            // Classnames
146            strClassMenuIsExposed = 'secondary-level-is-expanded',
147            strClassCurrentPage = 'is-current-page';
148
149        if (oMainElement.classList.contains(strClassMenuIsExposed)) {
150            oMainElement.classList.remove(strClassMenuIsExposed);
151            oMainElement.classList.remove(strClassCurrentPage);
152        } else {
153            this._refs.navItems.forEach(item => {
154                item.parentElement.classList.remove(strClassMenuIsExposed);
155                item.parentElement.classList.remove(strClassCurrentPage);
156            });
157            oMainElement.classList.add(strClassMenuIsExposed);
158        }
159    }
160
161    /**
162     * Handler for helping toggling between visible/non-visible on mobile devices
163     */
164    _onTogglClick () {
165        const
166            strMenuClassVisibility = 'main-list-is-visible',
167            strBodyClassMenuVisibility = 'main-navigation-is-visible';
168
169        if(this._props.visible) {
170            this._refs.body.classList.remove(strBodyClassMenuVisibility);
171            this._refs.el.classList.remove(strMenuClassVisibility);
172        } else {
173            this._refs.body.classList.add(strBodyClassMenuVisibility);
174            this._refs.el.classList.add(strMenuClassVisibility);
175        }
176
177        this._props.visible = !this._props.visible;
178    }
179}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.