Pure JavaScript multi-level drop-down menu.
At it's core, Droppy adds or removes CSS classes. This way you are able to
control the menu appearance, just editing the .droppy_drop
and
.droppy__drop--active
CSS classes.
<!-- Classic HTML menu -->
<nav>
<ul class="menu">
<li>
<a href="#">First level - Link #1</a>
<ul class="menu">
<li><a href="#">Second level - Link #1</a></li>
<li><a href="#">Second level - Link #2</a></li>
</ul>
</li>
<li><a href="#">First level - Link #2</a></li>
<li><a href="#">First level - Link #3</a></li>
</ul>
</nav>
Start using Droppy in three steps.
Download latest Droppy package from Github or via NPM or Bower.
# NPM
npm install droppy-menu --save
# Bower
bower install droppy-menu --save
Add dist/droppy.min.css
and dist/droppy.min.js
to your web page.
<link href="/path/to/droppy/dist/droppy.min.css" rel="stylesheet" media="screen">
<script src="/path/to/droppy/dist/droppy.min.js"></script>
Initialize Droppy in a custom script.
var element = document.querySelector( '.dropdown-menu' );
// Initialize Droppy.
var droppy = new Droppy( element, {
parentSelector: 'li',
dropdownSelector: 'li > ul.menu',
triggerSelector: 'a'
} );
That's it. You're all set to start using Droppy.
You can initialize Droppy in HTML, just adding data-droppy
attribute to the
menu element. Options can be set in its value using valid JSON.
<!-- Init with HTML -->
<nav class="dropdown-menu" data-droppy='{ "parentSelector": "li", "dropdownSelector": "li > ul.menu", "triggerSelector": "a", "closeOthers": true, "clickOutToClose": true, "clickEscToClose": true, "animationIn": '', "animationOut": '', "preventDefault": true }'>
To make Droppy work properly you have to describe your menu structure by
setting the options parentSelector
, dropdownSelector
and triggerSelector
.
// Default options.
var droppy = new Droppy( element, {
parentSelector: 'li',
dropdownSelector: 'li > ul',
triggerSelector: 'a',
closeOthers: true,
clickOutToClose: true,
clickEscToClose: true,
animationIn: '',
animationOut: '',
preventDefault: true
}, callbacks );
<nav class="dropdown-menu"> <!-- The Droppy's element -->
<ul class="menu">
<li> <!-- The parent selector "li" -->
<a href="#">Link #1</a> <!-- The trigger selector "a" -->
<ul class="menu"> <!-- The drop-down selector "li > ul" -->
<li><a href="#">Link #1</a></li>
<li><a href="#">Link #2</a></li>
</ul>
</li>
<li><a href="#">Link #2</a></li>
<li><a href="#">Link #3</a></li>
</ul>
</nav>
dropdownSelector - It's a valid CSS selector of your drop-down. In the
example above I have a drop-down when there is a <ul class="menu">
son of a
<li>
. That's why the dropdownSelector
is set to li > ul.menu
.
parentSelector - It's a valid CSS selector of your parent element. The
parent element have to contain the trigger element and the drop-down
element. It should be the closest parent. In the example above the closest
parent of both - dropdownSelector
and triggerSelector
- is the <li>
element. That's why the parentSelector
is set to li
.
triggerSelector - It's a valid CSS selector of the element that triggers
the open or close event. In the example above the trigger is the <a>
element.
That's why the triggerSelector
is set to a
.
closeOthers - A boolean value. Set to true
if you want keep open only
one drop-down at a time.
clickOutToClose - A boolean value. Set to true
if you want to close
all the drop-downs by clicking on the outside of the current menu.
clickEscToClose - A boolean value. Set to true
if you want to close
all the drop-downs by clicking ESC.
animationIn - A CSS class where is declared an animation. This class will be applied at the open of a drop-down and removed at the end of the animation.
animationOut - A CSS class where is declared an animation. This class will be applied at the close of a drop-down and removed at the end of the animation.
preventDefault - A boolean value. If the triggerSelector
is an element
that fires an event, you can prevent the execution of the default behavior
setting this option to true
. E.g. If triggerSelector
is a link, we want the
browser opens the drop-down, not follows the link. Setting preventDefault
to
true
prevents the browser to follow the link.
Methods are actions done by Droppy instances.
// Instantiate
var droppy = new Droppy( element, options, callbacks );
Initialize a Droppy object. It adds Droppy CSS classes and events.
// Init Droppy object
droppy.init();
Reset a Droppy instance to a pre-init state. It removes Droppy CSS classes and events.
// Reset Droppy instance to a pre-init state
droppy.destroy();
Open the given drop-down. If closeOthers
is set to true
, the other
drop-downs will be closed before opening the current one.
{Element|DroppyNode} dropdown
- The drop-down element to open.{Boolean} [withDescendants=false]
- Should open or not all the drop-downs
in the given drop-down.var dropdown = document.querySelector( '#menu-main .droppy__drop' )
// Open a drop-down
droppy.open( dropdown );
Close the given drop-down and all its descendants.
{Element|DroppyNode} dropdown
- The drop-down element to close.{Boolean} [withDescendants=true]
- Should close or not all the drop-downs
in the given drop-down.var dropdown = document.querySelector( '#menu-main .droppy__drop' )
// Close a drop-down
droppy.close( dropdown );
Open or close the given drop-down.
{Element|DroppyNode} dropdown
- The drop-down element to toggle.{Boolean} [withDescendants=undefined]
- Should toggle or not all the
drop-downs in the given drop-down.var dropdown = document.querySelector( '#menu-main .droppy__drop' )
// Toggle a dropdown
droppy.toggle( dropdown );
Open all drop-downs of a menu.
// Open all drop-downs
droppy.openAll();
Close all drop-downs of a menu.
// Close all drop-downs
droppy.closeAll();
Subscribe to an event.
{string} event
- The name of the event to subscribe to.{function} callback
- The function to call when the event is emitted.context
- The context to bind to the callback.// The callback function.
function alertOpen( event ) {
alert( 'Open!' );
console.log( event );
}
// Subscribe to open event.
droppy.on( 'open', alertOpen );
Subscribe to an event once.
{string} event
- The name of the event to subscribe to.{function} callback
- The function to call when the event is emitted.context
- The context to bind to the callback.// SUbscribe to open event once.
droppy.once( 'open', alertOpen );
Unsubscribe to an event. If no callback is provided, unsubscribe from all events.
{string} event
- The name of the event to unsubscribe from.{function} callback
- The function used when binding to the event.// Unsubscribe to open event.
droppy.off( 'open', alertOpen );
It returns true if the given Droppy instance is initialized, false otherwise.
var droppy = new Droppy( element, options );
// Check if initialized
var initialized = Droppy.prototype.isInitialized( droppy );
It returns the Droppy instance used by the given element.
var element = document.querySelector( '[data-droppy]' );
// Get the instance
var droppy = Droppy.prototype.getInstance( element );
Events are "things" that happen at a specific point of execution. You can listen to Droppy's events and react to them. Here's a list of Droppy's events.
init
- Dispatched when a Droppy object is initialized.destroy
- Dispatched when a Droppy object is destroyed.open
- Dispatched when a drop-down is opened.close
- Dispatched when a drop-down is closed.openAll
- Dispatched when all drop-downs of a menu are opened.closeAll
- Dispatched when all drop-downs of a menu are closed.DEPRECATED - Callbacks will be removed in v2.0.0 in favor of events.
Callbacks are function called at a specific point of execution. Callbacks does
not wait for animation end, this may cause the execution of afterOpen
,
afterClose
, afterOpenAll
and afterCloseAll
when the drop-down is not
completely opened or closed yet.
// Default callbacks.
var droppy = new Droppy( element, options, {
beforeOpen: null,
afterOpen: null,
beforeClose: null,
afterClose: null,
beforeOpenAll: null,
afterOpenAll: null,
beforeCloseAll: null,
afterCloseAll: null,
beforeInit: null,
afterInit: null,
beforeDestroy: null,
afterDestroy: null
} );
Define a callback in three steps.
Create your callback function.
function alertCallback() {
alert( 'Before open.' );
}
Assign the function to the callbacks
object.
var callbacks = {
beforeOpen: alertCallback
}
Create a Droppy object with the callbacks.
var droppy = new Droppy(element, options, callbacks);
Understanding how Droppy detect your drop-down menu structure, can help you set
*Selector
options correctly.
Droppy starts from dropdownSelector
to detect your drop-down menu structure.
For each drop-down, Droppy loops through element parents until reach the first
element that matches the parentSelector
. Once got the parent element, Droppy
selects the first element child of the parent element that matches the
triggerSelector
.
Instead of querying at every click the DOM, Droppy stores your drop-down menu
structure in the tree
property. The tree
is an array of DroppyNode
instances.
var droppy = new Droppy( element, options, callbacks );
// Print the tree
console.log( droppy.tree );
Droppy uses a bunch of polyfills to be compatible with old browsers. Here's a list of polyfills used.
Version | Tag | Published |
---|---|---|
1.1.1 | latest | 5yrs ago |