2015-03-31 123 views
0

我在js中创建了一个可扩展菜单。我用click事件添加open类,然后再次单击以删除该类。如何关闭可扩展菜单,点击外部div和js

我想关闭菜单,当我点击outisde菜单。我试着用document.addEventListener,但似乎没有工作。

function collapse() { 
    if (this.classList.contains('open')) { 
     this.classList.remove('open'); 
     document.removeEventListener('click', collapse, false); 
    } else { 
     this.classList.add('open'); 
     document.addEventListener('click', collapse, false); 
    } 
} 


var x = document.getElementsByClassName("toggle-menu"); 
for (var i = 0; i < x.length; i++) { 
    x[i].addEventListener('click', collapse, false); 
} 

这里小提琴http://jsfiddle.net/4cv220mc/

感谢

回答

1

我注意到你发布的代码关闭菜单,甚至当你点击菜单中的li要素之一 - 这是不可取的肯定,所以它最好是在点击菜单的h3元素时检查崩溃事件点击的目标并关闭/打开。

其次,你在这里找的是event.stopPropagation函数。这样,您可以将事件侦听器放在toggle-menu类和document.documentElement - 这将是html元素(您可以将它放在document.body上,但有时不会填满屏幕)。

所以菜单事件监听器会切换open类并停止进一步的传播。如果菜单事件侦听器是而不是先调用,那么现在只会调用html事件侦听器 - 它将检查是否有任何打开的菜单,如果是,将从所有菜单中删除open类。

这样你就可以拥有许多菜单,并在任何打开的菜单(包括另一个菜单)之外的任何地方点击来关闭它。我使用[].slice.call将所有菜单元素转换为数组,以便我可以调用forEach函数,我发现这更容易读/写,但您的计数器方法也是当然作品):

var html = document.documentElement, 
    menus = [].slice.call(document.getElementsByClassName('toggle-menu')); 

function menuClick(e){ 
    e.stopPropagation(); 
    if(e.target.tagName.toLowerCase()=='h3'){ 
     this.classList.toggle('open'); 
    } 
    var openMenus = document.querySelectorAll('.open.toggle-menu'); 
    for(var i=0;i<openMenus.length;i++){ 
     if(openMenus[i]==this) 
      continue; 
     openMenus[i].classList.remove('open'); 
    } 
} 
function bodyClick(e){ 
    if(document.querySelector('.toggle-menu.open')){ 
     menus.forEach(function(menu){ 
      if(menu.classList.contains('open')) 
       menu.classList.remove('open'); 
     }); 
    } 
} 
menus.forEach(function(menu){ 
    menu.addEventListener('click',menuClick,false); 
}); 
html.addEventListener('click',bodyClick,false); 

如果你想拥有菜单的同时打开(点击一个不应该关闭等),你可以删除var openMenusmenuClick功能启动的一部分。

这是一个小提琴:http://jsfiddle.net/811r0nzw/

+0

这正是我所需要的!非常感谢你@sidd – edo88 2015-03-31 12:17:54

0

HTML

<div class="wrapper"> 
<div class="toggle-menu"> 

<h3 class="toggle-label">Menu</h3> 

<ul class="toggle-body"> 
    <li>1</li> 
    <li>2</li> 
    <li>3</li> 
    <li>4</li> 
    <li>5</li> 
</ul> 
</div> 
</div> 

的CSS -

.toggle-menu { 
background-color:#ccc; 
} 
.toggle-body { 
    display:none; 
} 
.open .toggle-body { 
    display:block; 
} 
.wrapper { 
    width:100%; 
    height:500px; 
} 

JS -

function collapse() { 
    if (this.classList.contains('open')) { 
     this.classList.remove('open'); 
     document.removeEventListener('click', collapse, false); 
    } else { 
     this.classList.add('open'); 
     document.addEventListener('click', collapse, false); 
    } 
} 


var x = document.getElementsByClassName("toggle-menu"); 
for (var i = 0; i < x.length; i++) { 
    x[i].addEventListener('click', collapse, false); 
} 

var y = document.getElementsByClassName("wrapper"); 
for (var i = 0; i < y.length; i++) { 
    y[i].addEventListener('click', collapse, false); 
} 

我编辑在这里你的jsfiddle - http://jsfiddle.net/4cv220mc/5/