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