簡體   English   中英

如何使 addEventListener 'click' 在具有相同 class 的兩個菜單項上工作

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

頁碼: https://ensjotannklinikk.no/

這是一個小提琴

第一個名為“ 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;
    }
});

為什么這在手機上不起作用? 當單擊菜單項 Behandlinger ( .behandlinger-item ) 時,我希望子菜單 ( .behandlinger-meny ) 的高度設置為55px 它完美地工作,除了沒有在菜單項上點擊 mobile


意識到移動菜單有自己的<nav> ,這可能會影響事件偵聽器。 我已經更新了下面的小提琴和簡化結構以及核心問題。 現在似乎真的很接近一個簡單的解決方案。

簡化結構:

.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>

可運行版本:

 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>

由於您有兩個觸發器,並且您的事件偵聽器僅使用querySelector附加到第一個觸發器,因此第二個觸發器沒有偵聽器。

您可以使用querySelectorAll並在 for 循環中將事件偵聽器附加到每個選定的觸發器。 因為你想要一個過渡,你必須使用'max-height'而不是'height',因為過渡不適用於高度。

為了在單擊其他地方(觸發器或子菜單除外)時關閉子菜單,我制作了一個 function isRelated()來檢查單擊目標是觸發器本身、子菜單還是兩者的子菜單。

具有多個觸發器的工作示例(下面的 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 示例:

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

頁: https://ensjotannklinikk.no/forside-wip

這是一個小提琴

第一個名為“ 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;
    }
});

為什么這在手機上不起作用? 當單擊菜單項 Behandlinger ( .behandlinger-item ) 時,我希望子菜單 ( .behandlinger-meny ) 的高度設置為55px 它完美地工作,除了沒有在菜單項上點擊 mobile


意識到移動菜單有自己的<nav> ,這可能會影響事件偵聽器。 我已經更新了下面的小提琴和簡化結構以及核心問題。 現在似乎真的很接近一個簡單的解決方案。

簡化結構:

.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>

可運行版本:

 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