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