How to make addEventListener 'click' work on two menu items with same class - Printable Version +- 0Day Forums (https://zeroday.vip) +-- Forum: Coding (https://zeroday.vip/Forum-Coding) +--- Forum: CMS (https://zeroday.vip/Forum-CMS) +---- Forum: WordPress (https://zeroday.vip/Forum-WordPress) +---- Thread: How to make addEventListener 'click' work on two menu items with same class (/Thread-How-to-make-addEventListener-39-click-39-work-on-two-menu-items-with-same-class) |
How to make addEventListener 'click' work on two menu items with same class - wunderkind491940 - 07-27-2023 Page: [To see links please register here] Here's [a fiddle][1] The first menu item called "**Behandlinger**" is set up with this JS (courtesy of [biberman][2]) to make the submenu emerge and retract properly. ```js var submenu = document.querySelector('.behandlinger-meny'); var menuTrigger = document.querySelector('.behandlinger-item'); //javascript version of jQuery isChild() function isChild(item, parentItem) { while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY'){ if (item == parentItem){ return true; } item = item.parentNode; } return false; } menuTrigger.addEventListener('click', function() { submenu.style.height = '55px'; }); document.querySelector('body').addEventListener('click', function(e) { if ( !isChild(e.target, menuTrigger) && !isChild(e.target, submenu) ) { submenu.style.height = 0; } }); document.addEventListener('keyup', function(e) { if ( e.key == 'Escape' ) { submenu.style.height = 0; } }); ``` **Why is this not working on mobile?** I wish for the submenu (```.behandlinger-meny```) height set to ```55px``` when the menu item Behandlinger (```.behandlinger-item```) is clicked. It works perfectly, except **not on the menu item click on mobile**. --- Realized the mobile menu has a ```<nav>``` of its own, which may affect the event listener. I have updated both the fiddle and the simplified structure below as well as the core question. Seems really close to a simple solution now. Simplified structure: ```css .behandlinger-meny { height: 0; transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1); overflow: hidden; } ``` ```html <div id="wrapper"> <header> <nav class="main-menu"> <ul> <li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> <nav class="mobile-main-menu"> <ul> <li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> </header> <section> <!-- Separated to follow page scroll --> <div id="behandlinger"> <!-- Scroll to position on item click --> <nav class="behandlinger-meny"> <script></script> <!-- Script in question --> <ul> <li><a>Sub item 1</a></li> <li><a>Sub item 2</a></li> <li><a>Sub item 3</a></li> </ul> </nav> </div> </section> <main> … </main> </div> ``` Runnable version: <!-- begin snippet: js hide: true console: true babel: false --> <!-- language: lang-js --> var submenu = document.querySelector('.behandlinger-meny'); var menuTrigger = document.querySelector('.behandlinger-item'); //javascript version of jQuery isChild() function isChild(item, parentItem) { while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY'){ if (item == parentItem){ return true; } item = item.parentNode; } return false; } menuTrigger.addEventListener('click', function() { submenu.style.height = '55px'; }); document.querySelector('body').addEventListener('click', function(e) { if ( !isChild(e.target, menuTrigger) && !isChild(e.target, submenu) ) { submenu.style.height = 0; } }); document.addEventListener('keyup', function(e) { if ( e.key == 'Escape' ) { submenu.style.height = 0; } }); <!-- language: lang-css --> .behandlinger-meny { height: 0; transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1); overflow: hidden; } <!-- language: lang-html --> <div id="wrapper"> <header> <nav class="main-menu"> <ul> <li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> <nav class="mobile-main-menu"> <ul> <li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> </header> <section> <!-- Separated to follow page scroll --> <div id="behandlinger"> <!-- Scroll to position on item click --> <nav class="behandlinger-meny"> <script></script> <!-- Script in question --> <ul> <li><a>Sub item 1</a></li> <li><a>Sub item 2</a></li> <li><a>Sub item 3</a></li> </ul> </nav> </div> </section> <main> … </main> </div> <!-- end snippet --> [1]: [To see links please register here] [2]:[To see links please register here] RE: How to make addEventListener 'click' work on two menu items with same class - Prosubceiling333 - 07-27-2023 Since you have two triggers and your event listener is only attached to the first with ```querySelector``` the second trigger has no listener. You can use ```querySelectorAll``` and attach the event listener in a for loop to each selected trigger. Because you want a transition you have to use 'max-height' instead of 'height' since transition doesn't work with height. For closing the submenu when clicking somewhere else (except trigger or submenu) i made a function *isRelated()* that checks if the click target is the trigger itself, the submenu or a child of both. **Working example** with multiple triggers (jQuery example below): <!-- begin snippet: js hide: false console: false babel: false --> <!-- language: lang-js --> document.addEventListener('DOMContentLoaded', function() { var submenu = document.querySelector('.behandlinger-meny'); var menuTrigger = document.querySelectorAll('.behandlinger-item'); function isRelated(item, parentSelector) { while (item != undefined && item != null && item.tagName.toUpperCase() != 'BODY') { parents = document.querySelectorAll(parentSelector); for (i = 0; i < parents.length; i++) { if (item == parents[i]) { return true; } } item = item.parentNode; } return false; } for (i = 0; i < menuTrigger.length; i++) { menuTrigger[i].addEventListener('click', function() { submenu.style.maxHeight = '1000px'; }); } document.querySelector('body').addEventListener('click', function(e) { if (!isRelated(e.target, '.behandlinger-item') && !isRelated(e.target, '.behandlinger-meny')) { submenu.style.maxHeight = 0; } }); document.addEventListener('keyup', function(e) { if (e.key == 'Escape') { submenu.style.maxHeight = 0; } }); }); <!-- language: lang-css --> header { display: flex; } .behandlinger-meny { max-height: 0; width: 150px; background-color: #ddd; transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1); overflow: hidden; } <!-- language: lang-html --> <div id="wrapper"> <header> <nav class="main-menu"> <ul> <li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> <nav class="mobile-main-menu"> <ul> <li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> </header> <section> <div id="behandlinger"> <nav class="behandlinger-meny"> <ul> <li><a>Sub item 1</a></li> <li><a>Sub item 2</a></li> <li><a>Sub item 3</a></li> </ul> </nav> </div> </section> <main> … </main> </div> <!-- end snippet --> --- **jQuery example:** <!-- begin snippet: js hide: true console: false babel: false --> <!-- language: lang-js --> $().ready(function() { var submenu = $('.behandlinger-meny'); $('.behandlinger-item').on('click', function() { submenu.css('maxHeight', '1000px'); }); $('body').on('click', function(e) { if (!$(e.target).parents().is('.behandlinger-item') && !$(e.target).parents().is('.behandlinger-meny')) { submenu.css('maxHeight', 0); } }); $(document).on('keyup', function(e) { if (e.key == 'Escape') { submenu.css('maxHeight', 0); } }); }); <!-- language: lang-css --> header { display: flex; } .behandlinger-meny { max-height: 0; width: 150px; background-color: #ddd; transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1); overflow: hidden; } <!-- language: lang-html --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="wrapper"> <header> <nav class="main-menu"> <ul> <li class="behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> <nav class="mobile-main-menu"> <ul> <li class="mobile-item behandlinger-item"><a href="#behandlinger">Behandlinger</a></li> <li><a>Item 2</a></li> <li><a>Item 3</a></li> <li><a>Item 4</a></li> </ul> </nav> </header> <section> <div id="behandlinger"> <nav class="behandlinger-meny"> <ul> <li><a>Sub item 1</a></li> <li><a>Sub item 2</a></li> <li><a>Sub item 3</a></li> </ul> </nav> </div> </section> <main> … </main> </div> <!-- end snippet --> |