gpjuno13 Posted October 31, 2016 Share Posted October 31, 2016 (edited) Good day everyone! I will admit right off the hop that I know very little about javascript programming but I hope that with your help, I can learn something today. I've looked on w3 and elsewhere to find my answer but I have not been successful. I think what I'm trying to do is simple... Using w3.css, I am trying to create a navigation menu that will include more than one dropdown menu. I have the menu working to a point. Right now if I click on the three links with sub menus, the sub menus will display. However, they do not 'hide' unless I click on the top-menu link. That is, if I click on 'Training', the sub menu appears but will only disappear if I click on 'Training' again. Of course I want the sub-menu to disappear if I click anywhere outside the sub-menu or have another sub-menu appear if I click on its top-menu link. I've attached my html file for you to have a look. Any help and guidance would be greatly appreciated. Thanks so much! Have a great day! <!DOCTYPE html> <html> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css"> <body> <div class="w3-container"> <ul class="w3-navbar w3-light-grey"> <li><a href="#">Home</a></li> <li class="w3-dropdown-click"> <a onclick="myFunction()" href="#">Manuals <i class="fa fa-caret-down"></i></a> <div id="sub-menu" class="w3-dropdown-content w3-white w3-card-4"> <a href="#">Power Unit/Truck/Bus Safety Inspections and Standards</a> <a href="#">School Bus Safety Inspections and Standards</a> <a href="#">Trailer/Semi-Trailer Safety Inspections and Standards</a> <a href="#">Motorcycle Safety Inspections and Standards</a> </div> </li> <li class="w3-dropdown-click"> <a onclick="myFunction2()" href="#">Forms <i class="fa fa-caret-down"></i></a> <div id="sub-menu2" class="w3-dropdown-content w3-white w3-card-4"> <a href="#">Supply Form</a> <a href="#">Backup Forms</a> <a href="#">Station Application</a> </div> </li> <li class="w3-dropdown-click"> <a onclick="myFunction3()" href="#">Training <i class="fa fa-caret-down"></i></a> <div id="sub-menu3" class="w3-dropdown-content w3-white w3-card-4"> <a href="#">Option 1</a> <a href="#">Option 2</a> <a href="#">Option 3</a> </div> </li> <li><a href="#">Who to Call</a></li> </ul> </div> <script> function myFunction() { var x = document.getElementById("sub-menu"); if (x.className.indexOf("w3-show") == -1) { x.className += " w3-show"; }else { x.className = x.className.replace(" w3-show", ""); } } function myFunction2() { var x = document.getElementById("sub-menu2"); if (x.className.indexOf("w3-show") == -1) { x.className += " w3-show"; }else { x.className = x.className.replace(" w3-show", ""); } } function myFunction3() { var x = document.getElementById("sub-menu3"); if (x.className.indexOf("w3-show") == -1) { x.className += " w3-show"; }else { x.className = x.className.replace(" w3-show", ""); } } </script> </body> </html> test.html Edited October 31, 2016 by gpjuno13 Link to comment Share on other sites More sharing options...
Ingolme Posted October 31, 2016 Share Posted October 31, 2016 The solution to make something close when clicking anywhere on the page is to add an event listener to the body. We can take advantage of the event target to make sure that the menu only closes if you click on something that is not the menu. document.body.addEventListener("click", closeMenu, false); var menu = document.getElementbyId("my-menu"); function closeMenu(e) { var element = e.target; // This is the element that was clicked on // Make sure that none of the ancestors is the menu var foundMenu = false; while(element && !foundMenu) { if(element == menu) { // The menu was clicked on foundMenu = true; } element = element.parentNode; } // Close the menu if we didn't click on it if(!foundMenu) { // Hide menu // // } } Link to comment Share on other sites More sharing options...
gpjuno13 Posted October 31, 2016 Author Share Posted October 31, 2016 Thank you very much for your quick response, Foxy Mod. added your script snippet to my existing script code and added a div with an id of "menu" around my menu code but I could not get it to work. I've updated my original post so that my original html (with old javascript) is visible without the need to download the html file. I hope this helps. Link to comment Share on other sites More sharing options...
dsonesuk Posted November 1, 2016 Share Posted November 1, 2016 (edited) The event needs to be passed on to relevant functions <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Document Title</title> <link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css"> <style> /* body, html {height:100%;}*/ </style> </head> <body> <div class="w3-container"> <ul id="DS_Nav" class="w3-navbar w3-light-grey "> <li><a href="#">Home</a></li> <li class="w3-dropdown-click"> <a href="#">Manuals <i class="fa fa-caret-down"></i></a> <div class="w3-dropdown-content w3-white w3-card-4"> <a href="#">Power Unit/Truck/Bus Safety Inspections and Standards</a> <a href="#">School Bus Safety Inspections and Standards</a> <a href="#">Trailer/Semi-Trailer Safety Inspections and Standards</a> <a href="#">Motorcycle Safety Inspections and Standards</a> </div> </li> <li class="w3-dropdown-click"> <a href="#">Forms <i class="fa fa-caret-down"></i></a> <div class="w3-dropdown-content w3-white w3-card-4"> <a href="#">Supply Form</a> <a href="#">Backup Forms</a> <a href="#">Station Application</a> </div> </li> <li class="w3-dropdown-click"> <a href="#">Training <i class="fa fa-caret-down"></i></a> <div class="w3-dropdown-content w3-white w3-card-4"> <a href="#">Option 1</a> <a href="#">Option 2</a> <a href="#">Option 3</a> </div> </li> <li><a href="#">Who to Call</a></li> </ul> </div> <script> window.addEventListener("click", function(event) { closeMenu(event); }, false); var menu = document.getElementById('DS_Nav'); function closeMenu(e) { var element = e.target; // This is the element that was clicked on // Make sure that none of the ancestors is the menu var foundMenu = false; while (element && !foundMenu) { if (element === menu) { // The menu was clicked on foundMenu = true; } element = element.parentNode; } // Close the menu if we didn't click on it if (!foundMenu) { // Hide menu ClearActiveMenu(); } } window.onload = function() { var parentNav = document.getElementById('DS_Nav'); var navListItem = parentNav.getElementsByTagName('LI'); for (var i = 0; i < navListItem.length; i++) { if (navListItem[i].className.indexOf("w3-dropdown-click") === -1) { navListItem[i].getElementsByTagName('A')[0].addEventListener("click", function() { ClearActiveMenu(); }, false); } else { navListItem[i].getElementsByTagName('A')[0].addEventListener("click", function() { ShowActiveMenu(this); }, false); } } }; function ClearActiveMenu() { var z = document.getElementsByClassName('w3-dropdown-content'); for (var i = 0; i < z.length; i++) { z[i].className = z[i].className.replace(" w3-show", ""); } } function ShowActiveMenu(elem) { ClearActiveMenu(); var z = elem.parentNode.getElementsByTagName('div')[0]; z.className = z.className += " w3-show"; } </script> </body> </html> Also because body height might be less than browser viewport height, it would be better to use window instead. Edited November 1, 2016 by dsonesuk 1 Link to comment Share on other sites More sharing options...
gpjuno13 Posted November 7, 2016 Author Share Posted November 7, 2016 Wow dsonesuk! Thank you! That's perfect! Link to comment Share on other sites More sharing options...
Webby Posted August 22, 2017 Share Posted August 22, 2017 (edited) I need the same thing but for the NEW w3.css (version 4) The nav bar code is much different and so the javascript would need a small updating. I know this would help a great number of people since it is one of the small drawbacks to using w3.css in the "real world" Edited August 22, 2017 by Webby Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now