Skip to content Skip to sidebar Skip to footer

Close Menu When Click / Touch Outside Javascript

A css / javascript trigger menu doesnt close when someone click or touch outside. You have to press the menu button to close it. I tried some jquery functions like: $('#menucontai

Solution 1:

When you open the menu, you should listen for clicks on document. Then when the document is clicked you close the popup (and you remove the listener on the document as well).

PS: keep your listener on the menu-container as well ;)

Here is an example you can use (I edited your fiddle) :

(function(){
	//Remember if the menu is opened or notvar 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);
  
  functiontoggleMenu(){
  	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);
    }
  }
  
  functiononMenu_click(domEvent){
  	domEvent.stopPropagation();
    toggleMenu();
  }
  
  functiononDoc_click(domEvent){
  	domEvent.stopPropagation();
    toggleMenu();
  }
  
  functiononMenuContainer_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-menuli{width:192px;background-color:#666;}
.nav.sub-menu.current-menu-item > a{background-color:#666;}
.nava,
.show_menu{display:block;}
.nava{color:#fff;padding:7px14px;}
.nava:hover{color:white;background-color:#999;}
.nav.current-menu-item > a{color:#fff;background-color:#666;cursor:text;}
.navli{background-color:#666;}
.menu_control{display:block;color:#111111;cursor:pointer;margin:7px -27px0 -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;}
<spanid="menu_control"class="menu_control"><divclass="navicon-line"></div><divclass="navicon-line"></div><divclass="navicon-line"></div></span><ulid="menu-standard"class="nav"><liid="menu-item"><ahref="/">Home</a></li><liid="menu-item"><ahref="#">test</a><ulclass="sub-menu"><liid="menu-item"><ahref="#">test</a></li><liid="menu-item"><ahref="#">test</a></li><liid="menu-item"><ahref="#">test</a></li><liid="menu-item"><ahref="#">test</a></li></ul></li><liid="menu-item"><ahref="#">test</a></li></ul><br />
Content Content  Content 

It's not the best way to do it because you add several click listeners... You could have just one listener on the doc and do different things depending on the target of the event...

Solution 2:

Thanks to finding-closest-element-without-jquery my solution is based on:

  • window.onload: try to insert always your code in such handler to be sure all the elements are already loaded and so ready for your code
  • to test if an element has a class use menu.classList.contains('show_menu')
  • to add/remove classes use menu.classList.remove('show_menu'); or menu.classList.add('show_menu');
  • add a listener for the whole document so that if you clicked ouside your menu you can remove the corresponding show_menu if added

My snippet:

functionclosest(el, selector) {
  var matchesFn;

  // find vendor prefix
  ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
    if (typeofdocument.body[fn] == 'function') {
      matchesFn = fn;
      returntrue;
    }
    returnfalse;
  })

  var parent;

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

  returnnull;
}
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-standarddocument.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-menuli{width:192px;background-color:#666;}
.nav.sub-menu.current-menu-item > a{background-color:#666;}
.nava,
.show_menu{display:block;}
.nava{color:#fff;padding:7px14px;}
.nava:hover{color:white;background-color:#999;}
.nav.current-menu-item > a{color:#fff;background-color:#666;cursor:text;}
.navli{background-color:#666;}
.menu_control{display:block;color:#111111;cursor:pointer;margin:7px -27px0 -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;}
<spanclass="menu_control"><divclass="navicon-line"></div><divclass="navicon-line"></div><divclass="navicon-line"></div></span><ulid="menu-standard"class="nav"><liid="menu-item"><ahref="/">Home</a></li><liid="menu-item"><ahref="#">test</a><ulclass="sub-menu"><liid="menu-item"><ahref="#">test</a></li><liid="menu-item"><ahref="#">test</a></li><liid="menu-item"><ahref="#">test</a></li><liid="menu-item"><ahref="#">test</a></li></ul></li><liid="menu-item"><ahref="#">test</a></li></ul><br />
Content Content  Content

Post a Comment for "Close Menu When Click / Touch Outside Javascript"