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 $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 showCurrentLabel: 'Show this page', 35 // Change to "true" to use the active item as back link label. 36 useActiveItemAsBackLabel: false, 37 // Change to "true" to add a navigable link to the active item to its child 38 // menu. 39 useActiveItemAsLink: true 40 }; 41 42 $.DLMenu.prototype = { 43 _init : function( options ) { 44 45 // options 46 this.options = $.extend( true, {}, $.DLMenu.defaults, options ); 47 // cache some elements and initialize some variables 48 this._config(); 49 50 var animEndEventNames = { 51 'WebkitAnimation' : 'webkitAnimationEnd', 52 'OAnimation' : 'oAnimationEnd', 53 'msAnimation' : 'MSAnimationEnd', 54 'animation' : 'animationend', 55 "MozAnimation" : "animationend" 56 }, 57 transEndEventNames = { 58 'WebkitTransition' : 'webkitTransitionEnd', 59 'MozTransition' : 'transitionend', 60 'OTransition' : 'oTransitionEnd', 61 'msTransition' : 'MSTransitionEnd', 62 'transition' : 'transitionend' 63 }; 64 65 // animation end event name 66 if (animEndEventNames[ window.supportedAnimation ] != undefined) { 67 this.animEndEventName = animEndEventNames[ window.supportedAnimation ] + '.dlmenu'; 68 } else { 69 this.animEndEventName = animEndEventNames[ 'animation' ] + '.dlmenu'; 70 } 71 // transition end event name 72 if (transEndEventNames[ window.supportedTransition ] != undefined) { 73 this.transEndEventName = transEndEventNames[ window.supportedTransition ] + '.dlmenu'; 74 } else { 75 this.transEndEventName = transEndEventNames[ 'transition' ] + '.dlmenu'; 76 } 77 // support for css animations and css transitions 78 this.supportAnimations = window.supportsAnimations; 79 this.supportTransitions = window.supportsTransitions; 80 81 this._initEvents(); 82 83 }, 84 _config : function() { 85 var self = this; 86 this.open = false; 87 this.$trigger = this.$el.children( '.dl-trigger' ); 88 this.$menu = this.$el.children( 'ul.dl-menu' ); 89 this.$menuitems = this.$menu.find( 'li:not(.dl-back)' ); 90 this.$el.find( 'ul.dl-submenu' ).prepend( '<li class="dl-back"><a href="#">' + this.options.backLabel + '</a></li>' ); 91 this.$back = this.$menu.find( 'li.dl-back' ); 92 93 // Set the label text for the back link. 94 if (this.options.useActiveItemAsBackLabel) { 95 this.$back.each(function() { 96 var $this = $(this), 97 parentLabel = $this.parents('li:first').find('a:first').text(); 98 99 $this.find('a').html(parentLabel); 100 }); 101 } 102 // If the active item should also be a clickable link, create one and put 103 // it at the top of our menu. 104 if (this.options.useActiveItemAsLink) { 105 this.$el.find( 'ul.dl-submenu' ).prepend(function() { 106 var activeLi = $(this).parents('li:not(.dl-back):first'); 107 var parentli = activeLi.find('a:first'); 108 if (activeLi.hasClass('mobile-clickable')) 109 return '<li class="dl-parent"><a href="' + parentli.attr('href') + '">' + self.options.showCurrentLabel + '</a></li>'; 110 else 111 return ''; 112 }); 113 } 114 115 }, 116 _initEvents : function() { 117 118 var self = this; 119 120 this.$trigger.on( 'click.dlmenu', function() { 121 if( self.open ) { 122 self._closeMenu(); 123 } 124 else { 125 self._openMenu(); 126 // clicking somewhere else makes the menu close 127 $body.off( 'click' ).children().on( 'click.dlmenu', function() { 128 self._closeMenu() ; 129 } ); 130 131 } 132 return false; 133 } ); 134 135 this.$menuitems.on( 'click.dlmenu', function( event ) { 136 137 event.stopPropagation(); 138 139 var $item = $(this), 140 $submenu = $item.children( 'ul.dl-submenu' ); 141 142 // Only go to the next menu level if one exists AND the link isn't the 143 // one we added specifically for navigating to parent item pages. 144 if( ($submenu.length > 0) && !($(event.currentTarget).hasClass('dl-subviewopen'))) { 145 146 var $flyin = $submenu.clone().css( 'opacity', 0 ).insertAfter( self.$menu ), 147 onAnimationEndFn = function() { 148 self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classout ).addClass( 'dl-subview' ); 149 $item.addClass( 'dl-subviewopen' ).parents( '.dl-subviewopen:first' ).removeClass( 'dl-subviewopen' ).addClass( 'dl-subview' ); 150 $flyin.remove(); 151 }; 152 153 setTimeout( function() { 154 $flyin.addClass( self.options.animationClasses.classin ); 155 self.$menu.addClass( self.options.animationClasses.classout ); 156 if( self.supportAnimations ) { 157 self.$menu.on( self.animEndEventName, onAnimationEndFn ); 158 } 159 else { 160 onAnimationEndFn.call(); 161 } 162 163 self.options.onLevelClick( $item, $item.children( 'a:first' ).text() ); 164 } ); 165 166 return false; 167 168 } 169 else { 170 self.options.onLinkClick( $item, event ); 171 } 172 173 } ); 174 175 this.$back.on( 'click.dlmenu', function( event ) { 176 177 var $this = $( this ), 178 $submenu = $this.parents( 'ul.dl-submenu:first' ), 179 $item = $submenu.parent(), 180 181 $flyin = $submenu.clone().insertAfter( self.$menu ); 182 183 var onAnimationEndFn = function() { 184 self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classin ); 185 $flyin.remove(); 186 }; 187 188 setTimeout( function() { 189 $flyin.addClass( self.options.animationClasses.classout ); 190 self.$menu.addClass( self.options.animationClasses.classin ); 191 if( self.supportAnimations ) { 192 self.$menu.on( self.animEndEventName, onAnimationEndFn ); 193 } 194 else { 195 onAnimationEndFn.call(); 196 } 197 198 $item.removeClass( 'dl-subviewopen' ); 199 200 var $subview = $this.parents( '.dl-subview:first' ); 201 if( $subview.is( 'li' ) ) { 202 $subview.addClass( 'dl-subviewopen' ); 203 } 204 $subview.removeClass( 'dl-subview' ); 205 } ); 206 207 return false; 208 209 } ); 210 211 }, 212 closeMenu : function() { 213 if( this.open ) { 214 this._closeMenu(); 215 } 216 }, 217 _closeMenu : function() { 218 var self = this, 219 onTransitionEndFn = function() { 220 self.$menu.off( self.transEndEventName ); 221 self._resetMenu(); 222 }; 223 224 this.$menu.removeClass( 'dl-menuopen' ); 225 this.$menu.addClass( 'dl-menu-toggle' ); 226 this.$trigger.removeClass( 'dl-active' ); 227 228 if( this.supportTransitions ) { 229 this.$menu.on( this.transEndEventName, onTransitionEndFn ); 230 } 231 else { 232 onTransitionEndFn.call(); 233 } 234 235 this.open = false; 236 }, 237 openMenu : function() { 238 if( !this.open ) { 239 this._openMenu(); 240 } 241 }, 242 _openMenu : function() { 243 var self = this; 244 // clicking somewhere else makes the menu close 245 $body.off( 'click' ).on( 'click.dlmenu', function() { 246 self._closeMenu() ; 247 } ); 248 this.$menu.addClass( 'dl-menuopen dl-menu-toggle' ).on( this.transEndEventName, function() { 249 $( this ).removeClass( 'dl-menu-toggle' ); 250 } ); 251 this.$trigger.addClass( 'dl-active' ); 252 this.open = true; 253 }, 254 // resets the menu to its original state (first level of options) 255 _resetMenu : function() { 256 this.$menu.removeClass( 'dl-subview' ); 257 this.$menuitems.removeClass( 'dl-subview dl-subviewopen' ); 258 } 259 }; 260 261 var logError = function( message ) { 262 if ( window.console ) { 263 window.console.error( message ); 264 } 265 }; 266 267 $.fn.dlmenu = function( options ) { 268 if ( typeof options === 'string' ) { 269 var args = Array.prototype.slice.call( arguments, 1 ); 270 this.each(function() { 271 var instance = $.data( this, 'dlmenu' ); 272 if ( !instance ) { 273 logError( "cannot call methods on dlmenu prior to initialization; " + 274 "attempted to call method '" + options + "'" ); 275 return; 276 } 277 if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) { 278 logError( "no such method '" + options + "' for dlmenu instance" ); 279 return; 280 } 281 instance[ options ].apply( instance, args ); 282 }); 283 } 284 else { 285 this.each(function() { 286 var instance = $.data( this, 'dlmenu' ); 287 if ( instance ) { 288 instance._init(); 289 } 290 else { 291 instance = $.data( this, 'dlmenu', new $.DLMenu( options, this ) ); 292 } 293 }); 294 } 295 return this; 296 }; 297 298} )( 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.