/** * 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);