admin管理员组文章数量:1336118
Page: /
Here's a fiddle
The first menu item called "Behandlinger" is set up with this JS (courtesy of biberman) to make the submenu emerge and retract properly.
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:
.behandlinger-meny {
height: 0;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<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:
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;
}
});
.behandlinger-meny {
height: 0;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<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>
Page: https://ensjotannklinikk.no/
Here's a fiddle
The first menu item called "Behandlinger" is set up with this JS (courtesy of biberman) to make the submenu emerge and retract properly.
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:
.behandlinger-meny {
height: 0;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<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:
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;
}
});
.behandlinger-meny {
height: 0;
transition: all .3s cubic-bezier(0.4, 0.0, 0.2, 1);
overflow: hidden;
}
<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>
Share
Improve this question
edited May 23, 2021 at 11:31
Odiin
asked Apr 4, 2021 at 1:36
OdiinOdiin
15018 bronze badges
3
- I tested your page ensjotannklinikk.no/forside-wip with firefox on android and with my windows convertible and it worked in destop mode. So the touch event is perfectly interpreted as 'click'. But in mobile mode your menu has another style (hamburger etc.), so i think it's something with your css. --- Or could it be, that your javascript (where the event listener is declared) is dependent on screen resolution/media query (could wordpress do something like that)? – biberman Commented Apr 4, 2021 at 16:17
-
I see now that the mobile menu is a different
<nav>
and there are in fact two differentli.behandlinger-item
in the same document, the mobile version ing in second. Could this be the issue? – Odiin Commented Apr 4, 2021 at 16:39 - That was the bug ;) -> The example for the other question was just for one trigger. I answered this question here with an updated example for multiple triggers... – biberman Commented Apr 4, 2021 at 17:44
1 Answer
Reset to default 15 +50Since 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):
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;
}
});
});
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;
}
<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>
jQuery example:
$().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);
}
});
});
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;
}
<script src="https://cdnjs.cloudflare./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>
版权声明:本文标题:javascript - How to make addEventListener 'click' work on two menu items with same class - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742393699a2466494.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论