Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 596 Vote(s) - 3.52 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to make addEventListener 'click' work on two menu items with same class

#1
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]

Reply

#2
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 -->

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through