简体   繁体   English

如何使 addEventListener 'click' 在具有相同 class 的两个菜单项上工作

[英]How to make addEventListener 'click' work on two menu items with same class

Page: https://ensjotannklinikk.no/页码: 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.第一个名为“ Behandlinger ”的菜单项是用这个 JS(由biberman提供)设置的,以使子菜单正确出现和收回。

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.当单击菜单项 Behandlinger ( .behandlinger-item ) 时,我希望子菜单 ( .behandlinger-meny ) 的高度设置为55px It works perfectly, except not on the menu item click on mobile .它完美地工作,除了没有在菜单项上点击 mobile


Realized the mobile menu has a <nav> of its own, which may affect the event listener.意识到移动菜单有自己的<nav> ,这可能会影响事件侦听器。 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>

Since you have two triggers and your event listener is only attached to the first with querySelector the second trigger has no listener.由于您有两个触发器,并且您的事件侦听器仅使用querySelector附加到第一个触发器,因此第二个触发器没有侦听器。

You can use querySelectorAll and attach the event listener in a for loop to each selected trigger.您可以使用querySelectorAll并在 for 循环中将事件侦听器附加到每个选定的触发器。 Because you want a transition you have to use 'max-height' instead of 'height' since transition doesn't work with height.因为你想要一个过渡,你必须使用'max-height'而不是'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.为了在单击其他地方(触发器或子菜单除外)时关闭子菜单,我制作了一个 function isRelated()来检查单击目标是触发器本身、子菜单还是两者的子菜单。

Working example with multiple triggers (jQuery example below):具有多个触发器的工作示例(下面的 jQuery 示例):

 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: jQuery 示例:

 $().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.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>

Page: https://ensjotannklinikk.no/forside-wip页: https://ensjotannklinikk.no/forside-wip

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.第一个名为“ Behandlinger ”的菜单项是用这个 JS(由biberman提供)设置的,以使子菜单正确出现和收回。

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.当单击菜单项 Behandlinger ( .behandlinger-item ) 时,我希望子菜单 ( .behandlinger-meny ) 的高度设置为55px It works perfectly, except not on the menu item click on mobile .它完美地工作,除了没有在菜单项上点击 mobile


Realized the mobile menu has a <nav> of its own, which may affect the event listener.意识到移动菜单有自己的<nav> ,这可能会影响事件侦听器。 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM