2016-12-23 13 views
-1

Я не думаю, что это дублированный вопрос. Я пробовал некоторые из других решений, найденных на этом веб-сайте, без разрешения, которое я ищу. How do I detect a click outside an element?, например, использует event.stopPropagation(); и не работает с несколькими меню правильно для меня.Как я могу реализовать `window.onlick = function (event) {`, чтобы закрыть раскрывающееся меню?

То, что я пытаюсь выполнить, - это когда пользователь нажимает нигде вне раскрывающегося меню, открытое меню закрывается.

Мне нравится, как работает код javascript от w3schools.com, он делает то, что я ищу, однако мне не хватает того, что мне нужно для ввода в window.onclick = function (event){, чтобы адаптировать его в моей структуре кода.

Это пример файла, который я собрал, чтобы выделить то, что я пытаюсь реализовать.

<!DOCTYPE html> 
<html> 

<head> 
<style> 

li > ul{display:none;} 
.show {display:block;} 
.sub-nav ul { 
    background: #efefef; 
    background: linear-gradient(top, #efefef 0%, #bbbbbb 100%); 
    background: -moz-linear-gradient(top, #efefef 0%, #bbbbbb 100%); 
    background: -webkit-linear-gradient(top, #efefef 0%,#bbbbbb 100%); 
    box-shadow: 0px 0px 9px rgba(0,0,0,0.15); 
    padding: 0 20px; 
    border-radius: 0px; 
    list-style: none; 
    position: relative; 
} 
.sub-nav ul:after {content: ""; clear: both; display: block;} 
li {float: left;} 
.sub-nav ul li:hover { 
    background: #4b545f; 
    background: linear-gradient(top, #4f5964 0%, #5f6975 40%); 
    background: -moz-linear-gradient(top, #4f5964 0%, #5f6975 40%); 
    background: -webkit-linear-gradient(top, #4f5964 0%,#5f6975 40%); 
} 
.sub-nav ul li:hover a {color: #fff;} 
.sub-nav ul li a { 
    display: block; 
    padding: 20px 40px; 
    color: #757575; 
    text-decoration: none; 
} 
.sub-nav ul ul { 
    background: #5f6975; 
    border-radius: 0px; 
    padding: 0; 
    position: absolute; 
    top: 100%; 
} 
.sub-nav ul ul li { 
    float: none; 
    border-top: 1px solid #6b727c; 
    border-bottom: 1px solid #575f6a; 
    position: relative; 
} 
.sub-nav ul ul li a {padding: 15px 40px; color: #fff;} 
.sub-nav ul ul li a:hover {background: #4b545f;} 

</style> 
</head> 

<body> 

<!-- START: nav --> 
<div class="sub-nav"> 
       <div class="container"> 

        <ul> 
         <li class="active"><a href="#">ROOT 1</a></li> 
         <li><a href="#">ROOT 2</a></li> 
         <li><a href="#">ROOT 3</a></li> 
         <li><a href="#">ROOT 4</a></li> 
         <li><a href="#">ROOT 5</a></li> 

         <li id="drop-one"><a href="#">DROP 1</a> 
          <ul> 
           <li class="has-sub"><a href="#">SUB MENU 1</a></li> 
           <li class="has-sub"><a href="#">SUB MENU 2</a></li> 
           <li class="has-sub"><a href="#">SUB MENU 3</a></li> 
           <li class="has-sub"><a href="#">SUB MENU 4</a></li> 
          </ul> 
         </li> 


         <li id="drop-two"><a>DROP 2</a> 
          <ul> 
           <li class="has-sub"><a href="#">SUB MENU LONG TITLE 1</a></li> 
           <li class="has-sub"><a href="#">SUB MENU LONG TITLE 2</a></li> 
           <li class="has-sub"><a href="#">SUB MENU LONG TITLE 3</a></li> 
          </ul> 
         </li> 
        </ul> 

       </div> 
</div> 
<!-- END: nav --> 






</body> 
</html> 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<script> 
    jQuery("li:has(ul)").click(function(){ 
     jQuery("ul",this).toggleClass("show"); 
    }); 


window.onclick = function(event) { 
    if (!event.target.matches('??????')) { 

     var dropdowns = document.getElementsByClassName("??????"); 
     var i; 
     for (i=0; i<dropdowns.length; i++) { 
      var openDropdown = dropdowns[i]; 
      if (openDropdown.classList.contains('show')) { 
       openDropdown.classList.remove('show'); 
      } 
     } 
    } 
} 

</script> 

Должно быть как можно более конкретным, что заменить "??????" с тем чтобы этот скрипт работал. Если код html необходимо изменить, чтобы этот скрипт работал, пожалуйста, сообщите, спасибо!

window.onclick = function(event) { 
    if (!event.target.matches('??????')) { 

     var dropdowns = document.getElementsByClassName("??????"); 
     var i; 
     for (i=0; i<dropdowns.length; i++) { 
      var openDropdown = dropdowns[i]; 
      if (openDropdown.classList.contains('show')) { 
       openDropdown.classList.remove('show'); 
      } 
     } 
    } 
} 



UPDATE: 12/27/2016 Просто следовать, я смог придумать, что я думаю, необходимые изменения, чтобы достичь того, что было необходимо.

Сначала я добавил li, а классы ul "dropdown" и "is-open" соответственно.

<li class="dropdown"><a href="#">DROP 1</a> 
    <ul class="is-open"> 
     <li><a href="#">SUB MENU 1</a></li> 
     <li><a href="#">SUB MENU 2</a></li> 
     <li><a href="#">SUB MENU 3</a></li> 
     <li><a href="#">SUB MENU 4</a></li> 
    </ul> 
</li> 


<li class="dropdown"><a href="#">DROP 2</a> 
    <ul class="is-open"> 
     <li><a href="#">SUB MENU LONG TITLE 1</a></li> 
     <li><a href="#">SUB MENU LONG TITLE 2</a></li> 
     <li><a href="#">SUB MENU LONG TITLE 3</a></li> 
    </ul> 
</li> 

Во-вторых, я заменил предыдущий сценарий с:

<script> 


    // this is the function caller for click into drop down menu 
    $(document).ready(function(){ 
     // this to function call targets the drop down menu by elements 
     $("li:has(ul)").click(function(){ 
      // (IMPORTANT) code to hide existing open drop down menu before displaying new drop down menu 
      $(".is-open").hide(); 
      // code to toggle menu from drop down ROOT 
      $(this).find(".is-open").toggle(); 
     });// END: .click 
    });// END: .ready 

    //this script closes menu when clicked outside of drop down menu. 
    $(document).on("click", function(event){ 
     var $triggerOn = $(".dropdown"); 
     if($triggerOn !== event.target && !$triggerOn.has(event.target).length){ 
      $(".is-open").hide(); 
     }// END: if statement    
    });// END: .on 



</script> 

Это позволило мне осуществить то, что я желал с точки зрения нажав вне выпадающего меню, и меню закрывается.

Теперь я создал только одну оставшуюся проблему, щелкнув на корневом уровне «DROP x». Меню будет расширяться по щелчку, но второй щелчок на корневом уровне больше не будет закрывать выпадающее меню. Любые советы по разрешению этого?

. (Примечание: Если удалить $(".is-open").hide(); из сценария он восстанавливает щелчок, чтобы открыть, и нажмите, чтобы закрыть функциональность, однако при нажатии кнопки с «DROP 1» до «DROP 2» выпадающего меню будет оставаться открытым)

+0

Просто для того, чтобы следить, я смог придумать то, что, по моему мнению, является необходимой модификацией для достижения необходимого. –

+0

Решение ошибки кода jQuery можно найти здесь (http://stackoverflow.com/questions/41353337/jquery-code-for-multiple-clickable-drop-down-menu-has-errors-please-advise). –

ответ

0

Это решение реализует все необходимые компоненты и решает возникшую ошибку сценария jQuery.

<!DOCTYPE html> 
<html> 

<head> 

<style> 

li > ul{display:none;} 
.show {display:block;} 
.sub-nav ul { 
    background: #efefef; 
    background: linear-gradient(top, #efefef 0%, #bbbbbb 100%); 
    background: -moz-linear-gradient(top, #efefef 0%, #bbbbbb 100%); 
    background: -webkit-linear-gradient(top, #efefef 0%,#bbbbbb 100%); 
    box-shadow: 0px 0px 9px rgba(0,0,0,0.15); 
    padding: 0 20px; 
    border-radius: 0px; 
    list-style: none; 
    position: relative; 
} 
.sub-nav ul:after {content: ""; clear: both; display: block;} 
li {float: left;} 
.sub-nav ul li:hover { 
    background: #4b545f; 
    background: linear-gradient(top, #4f5964 0%, #5f6975 40%); 
    background: -moz-linear-gradient(top, #4f5964 0%, #5f6975 40%); 
    background: -webkit-linear-gradient(top, #4f5964 0%,#5f6975 40%); 
} 
.sub-nav ul li:hover a {color: #fff;} 
.sub-nav ul li a { 
    display: block; 
    padding: 20px 40px; 
    color: #757575; 
    text-decoration: none; 
} 
.sub-nav ul ul { 
    background: #5f6975; 
    border-radius: 0px; 
    padding: 0; 
    position: absolute; 
    top: 100%; 
} 
.sub-nav ul ul li { 
    float: none; 
    border-top: 1px solid #6b727c; 
    border-bottom: 1px solid #575f6a; 
    position: relative; 
} 
.sub-nav ul ul li a {padding: 15px 40px; color: #fff;} 
.sub-nav ul ul li a:hover {background: #4b545f;} 

</style> 

</head> 

<body> 

<!-- START: nav --> 
<div class="sub-nav"> 
       <div class="container"> 

        <ul> 
         <li class="active"><a href="#">ROOT 1</a></li> 
         <li><a href="#">ROOT 2</a></li> 
         <li><a href="#">ROOT 3</a></li> 
         <li><a href="#">ROOT 4</a></li> 
         <li><a href="#">ROOT 5</a></li> 

         <li class="dropdown"><a href="#">DROP 1</a> 
          <ul class="is-open"> 
           <li><a href="#">SUB MENU 1</a></li> 
           <li><a href="#">SUB MENU 2</a></li> 
           <li><a href="#">SUB MENU 3</a></li> 
           <li><a href="#">SUB MENU 4</a></li> 
          </ul> 
         </li> 


         <li class="dropdown"><a href="#">DROP 2</a> 
          <ul class="is-open"> 
           <li><a href="#">SUB MENU LONG TITLE 1</a></li> 
           <li><a href="#">SUB MENU LONG TITLE 2</a></li> 
           <li><a href="#">SUB MENU LONG TITLE 3</a></li> 
          </ul> 
         </li> 
        </ul> 

       </div> 
</div> 
<!-- END: nav --> 

</body> 
</html> 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<script> 
    // this is the function caller for click into drop down menu 
$(document).ready(function(){ 
    $("li:has(ul)").click(function(){ 
    if ($(this).find(".is-open").is(":visible")) { 
     $(".is-open").hide(); 
    } else { 
     $(".is-open").hide(); 
     $(this).find(".is-open").toggle(); 
    } 
    }); 
}); 
    //this script closes menu when clicked outside of drop down menu. 
    $(document).on("click", function(event){ 
     var $triggerOn = $(".dropdown"); 
     if($triggerOn !== event.target && !$triggerOn.has(event.target).length){ 
      $(".is-open").hide(); 
     }// END: if statement    
    });// END: .on 
</script>