点击/触摸外部JavaScript时关闭菜单

时间:2016-07-13 18:12:01

标签: javascript jquery html css

当有人点击或外面触摸时,css / javascript触发菜单不会关闭。

您必须按菜单按钮才能将其关闭。我尝试了一些jquery函数,如:

$('#menucontainer').click(function(event) {
    event.stopPropagation();
});

但这不起作用。在这里,我使用所有相关代码创建了一个简单的jsfiddle:

https://jsfiddle.net/4sgf84jL/

我很感激一些帮助。谢谢

2 个答案:

答案 0 :(得分:1)

当您打开菜单时,您应该听取文档的点击。然后单击文档时关闭弹出窗口(并删除文档上的侦听器)。

PS:将你的听众放在菜单容器上;)

以下是您可以使用的示例(我编辑了您的小提琴):

(function(){
	//Remember if the menu is opened or not
  var menuOpened = false;
	var menuElement = document.getElementById('menu_control');
  var menuContainer = document.getElementById('menu-standard');
  
  // Add click listener on menu icon
  menuElement.addEventListener('click', onMenu_click);
  
   // Add click listener on menu 
  menuContainer.addEventListener('click', onMenuContainer_click);
  
  function toggleMenu(){
  	menuOpened = !menuOpened;
  
  	if (menuOpened){
    	menuContainer.className += ' show_menu';
      document.addEventListener('click', onDoc_click);
    }
    else{
    	menuContainer.className = menuContainer.className.replace('show_menu', '').trim();
      document.removeEventListener('click', onDoc_click);
    }
  }
  
  function onMenu_click(domEvent){
  	domEvent.stopPropagation();
    toggleMenu();
  }
  
  function onDoc_click(domEvent){
  	domEvent.stopPropagation();
    toggleMenu();
  }
  
  function onMenuContainer_click(domEvent){
  	domEvent.stopPropagation();
  }
})();
.nav,
.menu_control{font-size:16px;line-height:23px;}
.nav{display:none;position:relative;width:219px;height:0;top:7px;list-style:none;z-index:9;background-color:#666;color:#fff}
.nav .sub-menu{list-style:none;padding-left:14px;}
.nav .sub-menu li{width:192px;background-color:#666;}
.nav .sub-menu .current-menu-item > a{background-color:#666;}
.nav a,
.show_menu{display:block;}
.nav a{color:#fff;padding:7px 14px;}
.nav a:hover{color:white;background-color:#999;}
.nav .current-menu-item > a{color:#fff;background-color:#666;cursor:text;}
.nav li{background-color:#666;}
.menu_control{display:block;color:#111111;cursor:pointer;margin:7px -27px 0 -27px;padding-right:27px;padding-left:27px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}
.navicon-line{width:32px;height:4px;border-radius:1px;margin-bottom:5px;background-color:#333;}
<span id="menu_control" class="menu_control">
    <div class="navicon-line"></div>
     <div class="navicon-line"></div>
    <div class="navicon-line"></div>
</span>
        
<ul id="menu-standard" class="nav">
<li id="menu-item"><a href="/">Home</a></li>
<li id="menu-item"><a href="#">test</a>
<ul class="sub-menu">
  <li id="menu-item"><a href="#">test</a></li>
  <li id="menu-item"><a href="#">test</a></li>
  <li id="menu-item"><a href="#">test</a></li>
  <li id="menu-item"><a href="#">test</a></li>
 </ul>
</li>
<li id="menu-item"><a href="#">test</a></li>
</ul>
<br />
Content Content  Content 

这不是最好的方法,因为你添加了几个点击监听器......你可以在doc上只有一个监听器,根据事件的目标做不同的事情......

答案 1 :(得分:0)

感谢finding-closest-element-without-jquery我的解决方案基于:

  • window.onload:尝试在此类处理程序中始终插入您的代码,以确保所有元素都已加载并为代码做好准备
  • 测试元素是否具有使用menu.classList.contains('show_menu')
  • 的类
  • 使用menu.classList.remove('show_menu');menu.classList.add('show_menu');
  • 添加/删除课程
  • 为整个文档添加一个监听器,这样如果您单击了菜单,则可以删除相应的show_menu(如果已添加)

我的片段:

function closest(el, selector) {
  var matchesFn;

  // find vendor prefix
  ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
    if (typeof document.body[fn] == 'function') {
      matchesFn = fn;
      return true;
    }
    return false;
  })

  var parent;

  // traverse parents
  while (el) {
    parent = el.parentElement;
    if (parent && parent[matchesFn](selector)) {
      return parent;
    }
    el = parent;
  }

  return null;
}
window.onload = function() {
  (function(){
    document.addEventListener('click', function(e) {
      if (e.target.className.indexOf('menu_control') == -1 &&
          e.target.className.indexOf('navicon-line') == -1 &&
          closest(e.target, '#menu-standard.nav') == null) {
        // menu-standard
        document.getElementById('menu-standard').classList.remove('show_menu');
      }
    }, false);
    var classes = document.getElementsByClassName('menu_control');
    for (i = 0; i < classes.length; i++) {
      classes[i].onclick = function() {
        var menu = this.nextElementSibling;
        if (menu.classList.contains('show_menu'))
          menu.classList.remove('show_menu');
        else
          menu.classList.add('show_menu');
      };
    }
  })();
}
.nav,
.menu_control{font-size:16px;line-height:23px;}
.nav{display:none;position:relative;width:219px;height:0;top:7px;list-style:none;z-index:9;background-color:#666;color:#fff}
.nav .sub-menu{list-style:none;padding-left:14px;}
.nav .sub-menu li{width:192px;background-color:#666;}
.nav .sub-menu .current-menu-item > a{background-color:#666;}
.nav a,
.show_menu{display:block;}
.nav a{color:#fff;padding:7px 14px;}
.nav a:hover{color:white;background-color:#999;}
.nav .current-menu-item > a{color:#fff;background-color:#666;cursor:text;}
.nav li{background-color:#666;}
.menu_control{display:block;color:#111111;cursor:pointer;margin:7px -27px 0 -27px;padding-right:27px;padding-left:27px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}
.navicon-line{width:32px;height:4px;border-radius:1px;margin-bottom:5px;background-color:#333;}
<span class="menu_control">
    <div class="navicon-line"></div>
     <div class="navicon-line"></div>
    <div class="navicon-line"></div>
</span>

<ul id="menu-standard" class="nav">
    <li id="menu-item"><a href="/">Home</a></li>
    <li id="menu-item"><a href="#">test</a>
        <ul class="sub-menu">
            <li id="menu-item"><a href="#">test</a></li>
            <li id="menu-item"><a href="#">test</a></li>
            <li id="menu-item"><a href="#">test</a></li>
            <li id="menu-item"><a href="#">test</a></li>
        </ul>
    </li>
    <li id="menu-item"><a href="#">test</a></li>
</ul>
<br />
Content Content  Content