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.hasClass('primary-navigation') && $('#perspective-menu-buttons').length > 0 ? $('#perspective-menu-buttons .dl-trigger') : this.$el.find( '.dl-trigger:first' ); 88 this.$menu = this.$el.find( 'ul.dl-menu:first' ); 89 this.$menuitems = this.$menu.find( 'li:not(.dl-back):not(.not-dlmenu)' ); 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 //event.preventDefault(); 139 140 var $item = $(this), 141 $submenu = $item.children( 'ul.dl-submenu' ), 142 level = 1; 143 144 if (!self.$menu.hasClass( 'dl-menuopen')) { 145 self.options.onLinkClick( $item, event ); 146 return; 147 } 148 149 var $itemList = $item.parent(); 150 while ($itemList.attr('id') != 'primary-menu') { 151 if ($itemList[0].nodeName.toUpperCase() == 'UL') { 152 level++; 153 } 154 $itemList = $itemList.parent(); 155 if (!$itemList.length) { 156 break; 157 } 158 } 159 if (level > 3) { 160 level = 3; 161 } 162 163 // Only go to the next menu level if one exists AND the link isn't the 164 // one we added specifically for navigating to parent item pages. 165 if( ($submenu.length > 0) && !($(event.currentTarget).hasClass('dl-subviewopen'))) { 166 167 var $flyin = $submenu.clone().addClass('level' + (level+1)).css( 'opacity', 0 ).insertAfter( self.$menu ), 168 onAnimationEndFn = function() { 169 self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classout ).addClass( 'dl-subview' ); 170 $item.addClass( 'dl-subviewopen' ).parents( '.dl-subviewopen:first' ).removeClass( 'dl-subviewopen' ).addClass( 'dl-subview' ); 171 $flyin.remove(); 172 }; 173 174 setTimeout( function() { 175 $flyin.addClass( self.options.animationClasses.classin ); 176 self.$menu.addClass( self.options.animationClasses.classout ); 177 if( self.supportAnimations ) { 178 self.$menu.on( self.animEndEventName, onAnimationEndFn ); 179 } 180 else { 181 onAnimationEndFn.call(); 182 } 183 184 self.options.onLevelClick( $item, $item.children( 'a:first' ).text() ); 185 } ); 186 187 return false; 188 189 } 190 else { 191 self.options.onLinkClick( $item, event ); 192 } 193 194 } ); 195 196 this.$back.on( 'click.dlmenu', function( event ) { 197 198 var $this = $( this ), 199 $submenu = $this.parents( 'ul.dl-submenu:first' ), 200 $item = $submenu.parent(), 201 level = 1; 202 203 var $itemList = $this.parent(); 204 while ($itemList.attr('id') != 'primary-menu') { 205 if ($itemList[0].nodeName.toUpperCase() == 'UL') { 206 level++; 207 } 208 $itemList = $itemList.parent(); 209 if (!$itemList.length) { 210 break; 211 } 212 } 213 if (level > 3) { 214 level = 3; 215 } 216 217 var $flyin = $submenu.clone().addClass('level' + level).insertAfter( self.$menu ); 218 219 var onAnimationEndFn = function() { 220 self.$menu.off( self.animEndEventName ).removeClass( self.options.animationClasses.classin ); 221 $flyin.remove(); 222 }; 223 224 setTimeout( function() { 225 $flyin.addClass( self.options.animationClasses.classout ); 226 self.$menu.addClass( self.options.animationClasses.classin ); 227 if( self.supportAnimations ) { 228 self.$menu.on( self.animEndEventName, onAnimationEndFn ); 229 } 230 else { 231 onAnimationEndFn.call(); 232 } 233 234 $item.removeClass( 'dl-subviewopen' ); 235 236 var $subview = $this.parents( '.dl-subview:first' ); 237 if( $subview.is( 'li' ) ) { 238 $subview.addClass( 'dl-subviewopen' ); 239 } 240 $subview.removeClass( 'dl-subview' ); 241 } ); 242 243 return false; 244 245 } ); 246 247 }, 248 closeMenu : function() { 249 if( this.open ) { 250 this._closeMenu(); 251 } 252 }, 253 _closeMenu : function() { 254 var self = this, 255 onTransitionEndFn = function() { 256 self.$menu.off( self.transEndEventName ); 257 self._resetMenu(); 258 }; 259 260 this.$menu.removeClass( 'dl-menuopen' ); 261 this.$menu.addClass( 'dl-menu-toggle' ); 262 this.$trigger.removeClass( 'dl-active' ); 263 264 if( this.supportTransitions ) { 265 this.$menu.on( this.transEndEventName, onTransitionEndFn ); 266 } 267 else { 268 onTransitionEndFn.call(); 269 } 270 271 this.open = false; 272 }, 273 openMenu : function() { 274 if( !this.open ) { 275 this._openMenu(); 276 } 277 }, 278 _openMenu : function() { 279 var self = this; 280 // clicking somewhere else makes the menu close 281 $body.off( 'click' ).on( 'click.dlmenu', function() { 282 self._closeMenu() ; 283 } ); 284 this.$menu.addClass( 'dl-menuopen dl-menu-toggle' ).on( this.transEndEventName, function() { 285 $( this ).removeClass( 'dl-menu-toggle' ); 286 } ); 287 this.$trigger.addClass( 'dl-active' ); 288 this.open = true; 289 }, 290 // resets the menu to its original state (first level of options) 291 _resetMenu : function() { 292 this.$menu.removeClass( 'dl-subview' ); 293 this.$menuitems.removeClass( 'dl-subview dl-subviewopen' ); 294 } 295 }; 296 297 var logError = function( message ) { 298 if ( window.console ) { 299 window.console.error( message ); 300 } 301 }; 302 303 $.fn.dlmenu = function( options ) { 304 if ( typeof options === 'string' ) { 305 var args = Array.prototype.slice.call( arguments, 1 ); 306 this.each(function() { 307 var instance = $.data( this, 'dlmenu' ); 308 if ( !instance ) { 309 logError( "cannot call methods on dlmenu prior to initialization; " + 310 "attempted to call method '" + options + "'" ); 311 return; 312 } 313 if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) { 314 logError( "no such method '" + options + "' for dlmenu instance" ); 315 return; 316 } 317 instance[ options ].apply( instance, args ); 318 }); 319 } 320 else { 321 this.each(function() { 322 var instance = $.data( this, 'dlmenu' ); 323 if ( instance ) { 324 instance._init(); 325 } 326 else { 327 instance = $.data( this, 'dlmenu', new $.DLMenu( options, this ) ); 328 } 329 }); 330 } 331 return this; 332 }; 333 334} )( 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.