This JavaScript code snippet helps you to create a menu. In this code a className
property of the document.documentElement
object to “js”, adds an event listener to the button
element and defines a function to close the menu
when the user clicks outside of it. The button. on click
function toggles the “menu-active” class on the menu
element using the class.toggle
method. The event listener is defined in the document.addEventListener
function checks whether the clicked element is not the dropdown
element and its descendant and removes the “menu-active” class from the menu
element using the class.removeClass
method. The code also includes a self-invoking function that defines the class
object, which provides several helper methods for manipulating CSS classes in the DOM, including hasClass
, addClass
, removeClass
, and toggleClass
.
How to Create JavaScript Menu
First of all, load the following assets into the head tag of your HTML document.
<meta name="viewport" content="width=device-width, initial-scale=1">
Create the HTML structure for the menu as follows:
<nav class="dropdown"> <button class="nav-toggle"><svg viewBox="0 0 16 16"><path d="M8.5 1c-4.142 0-7.5 3.358-7.5 7.5 0 4.143 3.358 7.5 7.5 7.5 4.143 0 7.5-3.357 7.5-7.5 0-4.142-3.357-7.5-7.5-7.5zm4 11h-8c-.276 0-.5-.225-.5-.5s.224-.5.5-.5h8c.275 0 .5.225.5.5s-.225.5-.5.5zm0-3h-8c-.276 0-.5-.225-.5-.5 0-.276.224-.5.5-.5h8c.275 0 .5.224.5.5 0 .275-.225.5-.5.5zm0-3h-8c-.276 0-.5-.224-.5-.5s.224-.5.5-.5h8c.275 0 .5.224.5.5s-.225.5-.5.5z"/></svg> Menu</button> <ul class="menu"> <li><a href="#0">one</a></li> <li><a href="#0">two</a></li> <li><a href="#0">three</a></li> <li><a href="#0">four</a></li> <li><a href="#0">five</a></li> </ul> </nav>
Style the menu using the following CSS styles:
body { width:15em; margin:5em auto; font:1em sans-serif; background:#222; } .dropdown { padding:1em 1em 0 1em; background:turquoise; display:block; color:#222; } .nav-toggle { -webkit-appearance: none; background:white; text-transform:uppercase; font-size:1em; padding:.5em; border:none; outline:none; transition: all 0.2s; cursor:pointer; } .nav-toggle:hover { background:#222; color:#fff; } .nav-toggle:focus, .menu a:focus { outline:1px solid red; } .nav-toggle svg { width:16px; height:16px; fill:red; vertical-align:top; margin-right:.25em; } .menu { list-style:none; padding:0; margin:1em 0 0 0; transition: all 0.8s cubic-bezier(.15,.7,0,1); } .menu a { display:block; color:turquoise; background:#222; text-decoration:none; padding:.5em .5em; outline:none; margin-bottom:.2em; transition: all 0.2s; } .menu a:hover { background:#fff; color:#222; } .js .menu { overflow: hidden; max-height: 0; } .js .menu-active { max-height:12em; padding-bottom:1em; }
Load the following scripts before closing the body tag:
<script src='https://raw.githubusercontent.com/desandro/classie/master/classie.js'></script>
Finally, add the following JavaScript function for its functionality:
document.documentElement.className = "js"; var menu = document.querySelector( '.menu' ), button = document.querySelector('.nav-toggle'), dropdown = document.querySelector('.dropdown'); button.onclick = function() { classie.toggle( menu, 'menu-active' ); }; // Close menu when clicking outside // See: https://css-tricks.com/dangers-stopping-event-propagation/ document.addEventListener('click', function(event) { if (event.target !== dropdown && !dropdown.contains(event.target)) { // hide the menu classie.removeClass(menu, "menu-active"); } }); /*! * classie v1.0.1 * class helper functions * from bonzo https://github.com/ded/bonzo * MIT license * * classie.has( elem, 'my-class' ) -> true/false * classie.add( elem, 'my-new-class' ) * classie.remove( elem, 'my-unwanted-class' ) * classie.toggle( elem, 'my-class' ) */ /*jshint browser: true, strict: true, undef: true, unused: true */ /*global define: false, module: false */ ( function( window ) { 'use strict'; // class helper functions from bonzo https://github.com/ded/bonzo function classReg( className ) { return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); } // classList support for class management // altho to be fair, the api sucks because it won't accept multiple classes at once var hasClass, addClass, removeClass; if ( 'classList' in document.documentElement ) { hasClass = function( elem, c ) { return elem.classList.contains( c ); }; addClass = function( elem, c ) { elem.classList.add( c ); }; removeClass = function( elem, c ) { elem.classList.remove( c ); }; } else { hasClass = function( elem, c ) { return classReg( c ).test( elem.className ); }; addClass = function( elem, c ) { if ( !hasClass( elem, c ) ) { elem.className = elem.className + ' ' + c; } }; removeClass = function( elem, c ) { elem.className = elem.className.replace( classReg( c ), ' ' ); }; } function toggleClass( elem, c ) { var fn = hasClass( elem, c ) ? removeClass : addClass; fn( elem, c ); } var classie = { // full names hasClass: hasClass, addClass: addClass, removeClass: removeClass, toggleClass: toggleClass, // short names has: hasClass, add: addClass, remove: removeClass, toggle: toggleClass }; // transport if ( typeof define === 'function' && define.amd ) { // AMD define( classie ); } else if ( typeof exports === 'object' ) { // CommonJS module.exports = classie; } else { // browser global window.classie = classie; } })( window );
That’s all! hopefully, you have successfully integrated the JavaScript code for the menu. If you have any questions or suggestions, feel free to comment below.