1/** 2 * jquery.dlmenu.js v1.0.1 3 * http://www.codrops.com 4 * 5 * Licensed under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7 * 8 * Copyright 2013, Codrops 9 * http://www.codrops.com 10 */ 11;( function( $, window, undefined ) { 12 13 'use strict'; 14 15 // global 16 var Modernizr = window.Modernizr, $body = $( 'body' ); 17 18 $.DLMenu = function( options, element ) { 19 this.$el = $( element ); 20 this._init( options ); 21 }; 22 23 // the options 24 $.DLMenu.defaults = { 25 // classes for the animation effects 26 animationClasses : { classin : 'dl-animate-in-1', classout : 'dl-animate-out-1' }, 27 // callback: click a link that has a sub menu 28 // el is the link element (li); name is the level name 29 onLevelClick : function( el, name ) { return false; }, 30 // callback: click a link that does not have a sub menu 31 // el is the link element (li); ev is the event obj 32 onLinkClick : function( el, ev ) { return false; }, 33 backLabel: 'Back', 34 // Change to "true" to use the active item as back link label. 35 useActiveItemAsBackLabel: false, 36 // Change to "true" to add a navigable link to the active item to its child 37 // menu. 38 useActiveItemAsLink: false, 39 // On close reset the menu to root 40 resetOnClose: true 41 }; 42 43 $.DLMenu.prototype = { 44 _init : function( options ) { 45 46 // options 47 this.options = $.extend( true, {}, $.DLMenu.defaults, options ); 48 // cache some elements and initialize some variables 49 this._config(); 50 51 var animEndEventNames = { 52 'WebkitAnimation' : 'webkitAnimationEnd', 53 'OAnimation' : 'oAnimationEnd', 54 'msAnimation' : 'MSAnimationEnd', 55 'animation' : 'animationend' 56 }, 57 transEndEventNames = { 58 'WebkitTransition' : 'webkitTransitionEnd', 59 'MozTransition' : 'transitionend', 60 'OTransition' : 'oTransitionEnd', 61 'msTransition' : 'MSTransitionEnd', 62 'transition' : 'transitionend' 63 }; 64 // animation end event name 65 this.animEndEventName = animEndEventNames[ Modernizr.prefixed( 'animation' ) ] + '.dlmenu'; 66 // transition end event name 67 this.transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ] + '.dlmenu'; 68 // support for css animations and css transitions 69 this.supportAnimations = Modernizr.cssanimations; 70 this.supportTransitions = Modernizr.csstransitions; 71 72 this._initEvents(); 73 74 }, 75 _config : function() { 76 this.open = false; 77 this.$trigger = this.$el.children( '.menu-trigger' ); 78 this.$menu = this.$el.children( 'ul.awesome-menu' ); 79 this.$menuitems = this.$menu.find( 'li:not(.menu-back)' ); 80 this.$el.find( 'ul.sub-menu' ).prepend( '<li class="menu-back"><a href="#">' + this.options.backLabel + '</a></li>' ); 81 this.$back = this.$menu.find( 'li.menu-back' ); 82 83 // Set the label text for the back link. 84 if (this.options.useActiveItemAsBackLabel) { 85 this.$back.each(function() { 86 var $this = $(this), 87 parentLabel = $this.parents('li:first').find('a:first').text(); 88 89 $this.find('a').html(parentLabel); 90 }); 91 } 92 // If the active item should also be a clickable link, create one and put 93 // it at the top of our menu. 94 if (this.options.useActiveItemAsLink) { 95 this.$el.find( 'ul.sub-menu' ).prepend(function() { 96 var parentli = $(this).parents('li:not(.menu-back):first').find('a:first'); 97 return '<li class="dl-parent"><a href="' + parentli.attr('href') + '">' + parentli.text() + '</a></li>'; 98 }); 99 } 100 101 }, 102 _initEvents : function() { 103 104 var self = this; 105 106 this.$trigger.on( 'click.dlmenu', function() { 107 if( self.open ) { 108 self._closeMenu(); 109 } 110 else { 111 self._openMenu(); 112 // clicking somewhere else makes the menu close 113 $body.off( 'click' ).children().on( 'click.dlmenu', function() { 114 self._closeMenu() ; 115 } ); 116 117 } 118 return false; 119 } ); 120 121 this.$menuitems.on( 'click.dlmenu', function( event ) { 122 123 event.stopPropagation(); 124 125 var $item = $(this), 126 $submenu = $item.children( 'ul.sub-menu' ); 127 128 // Only go to the next menu level if one exists AND the link isn't the 129 // one we added specifically for navigating to parent item pages. 130 if( ($submenu.length > 0) && !($(event.currentTarget).hasClass('dl-subviewopen'))) { 131 132 var $flyin = $submenu.clone().css( 'opacity', 0 ).insertAfter( self.$menu ), 133 onAnimationEndFn = function() { 134 self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classout ).addClass( 'dl-subview' ); 135 $item.addClass( 'dl-subviewopen' ).parents( '.dl-subviewopen:first' ).removeClass( 'dl-subviewopen' ).addClass( 'dl-subview' ); 136 $flyin.remove(); 137 }; 138 139 setTimeout( function() { 140 $flyin.addClass( self.options.animationClasses.classin ); 141 self.$menu.addClass( self.options.animationClasses.classout ); 142 if( self.supportAnimations ) { 143 self.$menu.on( self.animEndEventName, onAnimationEndFn ); 144 } 145 else { 146 onAnimationEndFn.call(); 147 } 148 149 self.options.onLevelClick( $item, $item.children( 'a:first' ).text() ); 150 } ); 151 152 return false; 153 154 } 155 else { 156 self.options.onLinkClick( $item, event ); 157 } 158 159 } ); 160 161 this.$back.on( 'click.dlmenu', function( event ) { 162 163 var $this = $( this ), 164 $submenu = $this.parents( 'ul.sub-menu:first' ), 165 $item = $submenu.parent(), 166 167 $flyin = $submenu.clone().insertAfter( self.$menu ); 168 169 var onAnimationEndFn = function() { 170 self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classin ); 171 $flyin.remove(); 172 }; 173 174 setTimeout( function() { 175 $flyin.addClass( self.options.animationClasses.classout ); 176 self.$menu.addClass( self.options.animationClasses.classin ); 177 if( self.supportAnimations ) { 178 self.$menu.on( self.animEndEventName, onAnimationEndFn ); 179 } 180 else { 181 onAnimationEndFn.call(); 182 } 183 184 $item.removeClass( 'dl-subviewopen' ); 185 186 var $subview = $this.parents( '.dl-subview:first' ); 187 if( $subview.is( 'li' ) ) { 188 $subview.addClass( 'dl-subviewopen' ); 189 } 190 $subview.removeClass( 'dl-subview' ); 191 } ); 192 193 return false; 194 195 } ); 196 197 }, 198 closeMenu : function() { 199 if( this.open ) { 200 this._closeMenu(); 201 } 202 }, 203 _closeMenu : function() { 204 var self = this, 205 onTransitionEndFn = function() { 206 self.$menu.off( self.transEndEventName ); 207 if( self.options.resetOnClose ){ 208 self._resetMenu(); 209 } 210 }; 211 212 this.$menu.removeClass( 'awesome-menuopen' ); 213 this.$menu.addClass( 'awesome-menu-toggle' ); 214 this.$trigger.removeClass( 'dl-active' ); 215 216 if( this.supportTransitions ) { 217 this.$menu.on( this.transEndEventName, onTransitionEndFn ); 218 } 219 else { 220 onTransitionEndFn.call(); 221 } 222 223 this.open = false; 224 }, 225 openMenu : function() { 226 if( !this.open ) { 227 this._openMenu(); 228 } 229 }, 230 _openMenu : function() { 231 var self = this; 232 // clicking somewhere else makes the menu close 233 $body.off( 'click' ).on( 'click.dlmenu', function() { 234 self._closeMenu() ; 235 } );
236 this.$menu.addClass( 'awesome-menuopen awesome-menu-toggle' ).on( this.transEndEventName, function() { 237 $( this ).removeClass( 'awesome-menu-toggle' ); 238 } ); 239 this.$trigger.addClass( 'dl-active' ); 240 this.open = true; 241 }, 242 // resets the menu to its original state (first level of options) 243 _resetMenu : function() { 244 this.$menu.removeClass( 'dl-subview' ); 245 this.$menuitems.removeClass( 'dl-subview dl-subviewopen' ); 246 } 247 }; 248 249 var logError = function( message ) { 250 if ( window.console ) { 251 window.console.error( message ); 252 } 253 }; 254 255 $.fn.dlmenu = function( options ) { 256 if ( typeof options === 'string' ) { 257 var args = Array.prototype.slice.call( arguments, 1 ); 258 this.each(function() { 259 var instance = $.data( this, 'dlmenu' ); 260 if ( !instance ) { 261 logError( "cannot call methods on dlmenu prior to initialization; " + 262 "attempted to call method '" + options + "'" ); 263 return; 264 } 265 if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) { 266 logError( "no such method '" + options + "' for dlmenu instance" ); 267 return; 268 } 269 instance[ options ].apply( instance, args ); 270 }); 271 } 272 else { 273 this.each(function() { 274 var instance = $.data( this, 'dlmenu' ); 275 if ( instance ) { 276 instance._init(); 277 } 278 else { 279 instance = $.data( this, 'dlmenu', new $.DLMenu( options, this ) ); 280 } 281 }); 282 } 283 return this; 284 }; 285 286} )( jQuery, window );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.