/**
* jquery.dlmenu.js v1.0.1
* http://www.codrops.com
*
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Copyright 2013, Codrops
* http://www.codrops.com
*/;
(function ($, window, undefined) {
'use strict';
// global
var Modernizr = window.Modernizr,
$body = $('body');
$.DLMenu = function (options, element) {
this.$el = $(element);
this._init(options);
};
// the options
$.DLMenu.defaults = {
// classes for the animation effects
animationClasses: {
classin : 'dl-animate-in-1',
classout: 'dl-animate-out-1'
},
// callback: click a link that has a sub menu
// el is the link element (li); name is the level name
onLevelClick : function (el, name) {
return false;
},
// callback: click a link that does not have a sub menu
// el is the link element (li); ev is the event obj
onLinkClick : function (el, ev) {
return false;
}
};
$.DLMenu.prototype = {
_init : function (options) {
// options
this.options = $.extend(true, {}, $.DLMenu.defaults, options);
// cache some elements and initialize some variables
this._config();
var animEndEventNames = {
'WebkitAnimation': 'webkitAnimationEnd',
'OAnimation' : 'oAnimationEnd',
'msAnimation' : 'MSAnimationEnd',
'animation' : 'animationend'
},
transEndEventNames = {
'WebkitTransition': 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'MSTransitionEnd',
'transition' : 'transitionend'
};
// animation end event name
this.animEndEventName = animEndEventNames[Modernizr.prefixed('animation')] + '.dlmenu';
// transition end event name
this.transEndEventName = transEndEventNames[Modernizr.prefixed('transition')] + '.dlmenu',
// support for css animations and css transitions
this.supportAnimations = Modernizr.cssanimations,
this.supportTransitions = Modernizr.csstransitions;
this._initEvents();
},
_config : function () {
this.open = false;
this.$trigger = this.$el.children('.dl-trigger');
this.$menu = this.$el.children('ul.dl-menu');
this.$menuitems = this.$menu.find('li:not(.dl-back)');
this.$el.find('ul.dl-submenu').prepend('
Back');
this.$back = this.$menu.find('li.dl-back');
},
_initEvents: function () {
var self = this;
this.$trigger.on('click.dlmenu', function () {
if (self.open) {
self._closeMenu();
} else {
self._openMenu();
}
return false;
});
this.$menuitems.on('click.dlmenu', function (event) {
var window_width = $(window).width();
if (window_width <= 992) {
event.stopPropagation();
var $item = $(this),
$submenu = $item.children('ul.dl-submenu');
if ($submenu.length > 0) {
var $flyin = $submenu.clone().css('opacity', 0).insertAfter(self.$menu),
onAnimationEndFn = function () {
self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classout).addClass('dl-subview');
$item.addClass('dl-subviewopen').parents('.dl-subviewopen:first').removeClass('dl-subviewopen').addClass('dl-subview');
$flyin.remove();
};
setTimeout(function () {
$flyin.addClass(self.options.animationClasses.classin);
self.$menu.addClass(self.options.animationClasses.classout);
if (self.supportAnimations) {
self.$menu.on(self.animEndEventName, onAnimationEndFn);
} else {
onAnimationEndFn.call();
}
self.options.onLevelClick($item, $item.children('a:first').text());
});
return false;
} else {
self.options.onLinkClick($item, event);
}
}
});
this.$back.on('click.dlmenu', function (event) {
var $this = $(this),
$submenu = $this.parents('ul.dl-submenu:first'),
$item = $submenu.parent(),
$flyin = $submenu.clone().insertAfter(self.$menu);
var onAnimationEndFn = function () {
self.$menu.off(self.animEndEventName).removeClass(self.options.animationClasses.classin);
$flyin.remove();
};
setTimeout(function () {
$flyin.addClass(self.options.animationClasses.classout);
self.$menu.addClass(self.options.animationClasses.classin);
if (self.supportAnimations) {
self.$menu.on(self.animEndEventName, onAnimationEndFn);
} else {
onAnimationEndFn.call();
}
$item.removeClass('dl-subviewopen');
var $subview = $this.parents('.dl-subview:first');
if ($subview.is('li')) {
$subview.addClass('dl-subviewopen');
}
$subview.removeClass('dl-subview');
});
return false;
});
},
closeMenu : function () {
if (this.open) {
this._closeMenu();
}
},
_closeMenu : function () {
var self = this,
onTransitionEndFn = function () {
self.$menu.off(self.transEndEventName);
self._resetMenu();
};
this.$menu.removeClass('dl-menuopen');
this.$menu.addClass('dl-menu-toggle');
this.$trigger.removeClass('dl-active');
if (this.supportTransitions) {
this.$menu.on(this.transEndEventName, onTransitionEndFn);
} else {
onTransitionEndFn.call();
}
this.open = false;
},
openMenu : function () {
if (!this.open) {
this._openMenu();
}
},
_openMenu : function () {
var self = this;
// clicking somewhere else makes the menu close
$body.off('click').on('click.dlmenu', function () {
self._closeMenu();
});
this.$menu.addClass('dl-menuopen dl-menu-toggle').on(this.transEndEventName, function () {
$(this).removeClass('dl-menu-toggle');
});
this.$trigger.addClass('dl-active');
this.open = true;
},
// resets the menu to its original state (first level of options)
_resetMenu : function () {
this.$menu.removeClass('dl-subview');
this.$menuitems.removeClass('dl-subview dl-subviewopen');
}
};
var logError = function (message) {
if (window.console) {
window.console.error(message);
}
};
$.fn.dlmenu = function (options) {
if (typeof options === 'string') {
var args = Array.prototype.slice.call(arguments, 1);
this.each(function () {
var instance = $.data(this, 'dlmenu');
if (!instance) {
logError("cannot call methods on dlmenu prior to initialization; " + "attempted to call method '" + options + "'");
return;
}
if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
logError("no such method '" + options + "' for dlmenu instance");
return;
}
instance[options].apply(instance, args);
});
} else {
this.each(function () {
var instance = $.data(this, 'dlmenu');
if (instance) {
instance._init();
} else {
instance = $.data(this, 'dlmenu', new $.DLMenu(options, this));
}
});
}
return this;
};
})(jQuery, window);