
Mobile Swipe Menu is a vanilla JavaScript library that creates touch-enabled off-canvas side menus for modern web applications.
It supports left and right slide modes and binds to any DOM element through a single constructor call.
Features:
- Supports right-edge and left-edge slide modes for offcanvas panel direction.
- Configurable panel width set in pixels at instantiation.
- Adjustable hook zone that protrudes from the panel edge as a drag trigger area.
- Percentage-based hook width calculation relative to the current viewport width.
- Full-body swipe detection mode that reacts to gestures across the entire window surface.
- Programmatic open, close, and toggle controls for button-driven interactions.
- Runtime swipe lock and unlock for disabling gesture input on demand.
- Lifecycle callbacks for swipe start, stop, drag, panel opened, and panel closed states.
Use Cases:
- Mobile navigation drawers for single-page apps.
- Off-canvas filter panels in e-commerce product listings.
- Side notification or chat drawers.
- Settings panels in mobile dashboards.
How to use it:
1. Download the package and load the mobile-swipe-menu.min.js script in the document.
<script src="js/mobile-swipe-menu.min.js"></script>
2. Attach the swipe menu to the nav panel element. The constructor accepts a CSS selector string or a direct DOM element reference as its first argument, and an options object as its second.
<!-- Buttons for manual menu control -->
<button id="showDrawer" type="button">Open navigation</button>
<button id="flipDrawer" type="button">Toggle navigation</button>
<button id="hideDrawer" type="button">Close navigation</button>
<!-- Offcanvas navigation panel -->
<nav id="navDrawer" aria-label="Mobile navigation">
<ul>
<li><a href="/docs/">Docs</a></li>
<li><a href="/components/">Components</a></li>
<li><a href="/patterns/">Patterns</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>/* Give the menu a visible surface */
#navDrawer {
top: 0;
bottom: 0;
background: #111;
color: #fff;
overflow-y: auto;
z-index: 1000;
}
/* Reset the list for a clean vertical menu */
#navDrawer ul {
margin: 0;
padding: 24px 0;
list-style: none;
}
/* Style menu links */
#navDrawer a {
display: block;
padding: 14px 20px;
color: inherit;
text-decoration: none;
}const quickMenu = new MobileSwipeMenu('#navDrawer', {
// Set the drawer side
mode: 'right',
// Set a visible width for the drawer
width: 300
});3. All configuration options:
mode(string): Sets the slide direction of the panel. Accepts'right'or'left'. Default:'right'.width(number): Sets the panel width in pixels. Default:0.hookWidth(number): Sets the pixel width of the drag tab that protrudes from the panel edge. Default:30.useHookWidthPercentage(boolean): Whentrue, the library treatshookWidthas a percentage of the viewport width. Default:false.enableBodyHook(boolean): Whentrue, the entire document body becomes the swipe trigger zone. Default:false.events(object): An object containing named callback functions for each lifecycle event. Default:{}.
4. API methods.
// Opens the panel sideNav.openMenu(); // Closes the panel sideNav.closeMenu(); // Toggles the panel between open and closed sideNav.toggleMenu(); // Disables swipe gesture detection at runtime sideNav.disableSwipe(); // Re-enables swipe gesture detection after it has been disabled sideNav.enableSwipe();
5. Events. Pass an events object to the constructor to hook into the swipe lifecycle. Each property is a named callback.
const quickMenu = new MobileSwipeMenu('#navDrawer', {
events: {
// Fires when the user first contacts the swipe surface
start: function () {
console.log('Swipe initiated');
},
// Fires when the user releases the swipe surface
stop: function () {
console.log('Swipe released');
},
// Fires continuously while the panel is being dragged
drag: function (swipe) {
console.log('Current swipe state:', swipe);
},
// Fires once the panel reaches the fully open position
opened: function () {
console.log('Panel fully open');
},
// Fires once the panel reaches the fully closed position
closed: function () {
console.log('Panel fully closed');
}
}
});






