1 /*! 2 * A simple jQuery plugin for creating animated drilldown menus. 3 * 4 * @name jQuery Drilldown 5 * @version 0.1.2 6 * @requires jQuery v1.7+ 7 * @author Aleksandras Nelkinas 8 * @license [MIT]{@link http://opensource.org/licenses/mit-license.php} 9 * 10 * Copyright (c) 2013 Aleksandras Nelkinas 11 */ 12 13 ;(function (factory) { 14 if (typeof define === 'function' && define.amd) { 15 // AMD support 16 define(['jquery'], factory); 17 } else { 18 factory(jQuery); 19 } 20 }(function ($, undefined) { 21 22 'use strict'; 23 24 var pluginName = 'drilldown', 25 defaults; 26 27 defaults = { 28 event: 'click', 29 selector: 'a', 30 speed: 100, 31 cssClass: { 32 container: pluginName + '-container', 33 root: pluginName + '-root', 34 sub: pluginName + '-sub', 35 back: pluginName + '-back' 36 } 37 }; 38 39 function Plugin(element, options) { 40 this._name = pluginName; 41 this._defaults = defaults; 42 43 this.element = element; 44 this.$element = $(element); 45 46 this.options = $.extend({}, defaults, options); 47 48 this.init(); 49 } 50 51 Plugin.prototype = { 52 53 history: [], 54 css: { 55 'float': 'left', 56 'width': null 57 }, 58 59 /** 60 * Initializes plugin. 61 */ 62 init: function () { 63 var self = this; 64 65 this.$container = this.$element.find('.' + this.options.cssClass.container); 66 this.$element.on(this.options.event, this.options.selector, function (e) { 67 self.handleAction.call(self, e, $(this)); 68 }); 69 }, 70 71 /** 72 * Handles user action and decides whether or not and where to drill. 73 * 74 * @param {jQuery.Event} e 75 * @param {jQuery} $trigger 76 */ 77 handleAction: function (e, $trigger) { 78 var $next = $trigger.nextAll('.' + this.options.cssClass.sub), 79 preventDefault = true; 80 81 if ($next.length) { 82 this.down($next); 83 } else if ($trigger.closest('.' + this.options.cssClass.back).length) { 84 this.up(); 85 } else { 86 preventDefault = false;
87 } 88 89 if (preventDefault && $trigger.prop('tagName') === 'A') { 90 e.preventDefault(); 91 } 92 }, 93 94 /** 95 * Drills down (deeper). 96 * 97 * @param {jQuery} $next 98 */ 99 down: function ($next) { 100 var self = this, 101 $current; 102 103 if (!$next.length) { 104 return; 105 } 106 107 this.css.width = this.$element.outerWidth(); 108 this.$container.width(this.css.width * 2); 109 110 $current = this.$container.find('.' + this.options.cssClass.root).first(); 111 112 $next = $current.clone().html($next.html()); 113 this.$container.append($next); 114 115 this.animateDrilling(-1 * this.css.width, function () { 116 var $current = $next.prev(); 117 118 self.history.push($current); 119 120 self.restoreState.call(self, $current, $next); 121 }); 122 }, 123 124 /** 125 * Drills up (back). 126 */ 127 up: function () { 128 var self = this, 129 $next = this.history.pop(); 130 131 this.css.width = this.$element.outerWidth(); 132 this.$container.width(this.css.width * 2); 133 134 this.$container.prepend($next); 135 136 this.animateDrilling(0, function () { 137 var $current = $next.next(); 138 139 self.restoreState.call(self, $current, $next); 140 }); 141 }, 142 143 /** 144 * Animates drilling process. 145 * 146 * @param {Number} marginLeft Target margin-left. 147 * @param {Function} callback 148 */ 149 animateDrilling: function (marginLeft, callback) { 150 var $roots = this.$container.children('.' + this.options.cssClass.root); 151 152 $roots.css(this.css); 153 154 // if( marginLeft === 0 ) { 155 156 // this.$container.animate( { 'height': $roots.eq(0).height() }, this.options.speed ); 157 158 // } else { 159 160 // this.$container.animate( { 'height': $roots.eq(1).height() }, this.options.speed ); 161 162 // } 163 164 165 166 $roots.first().animate({ 167 'margin-left': marginLeft 168 }, this.options.speed, callback); 169 }, 170 171 /** 172 * Restores initial menu's state. 173 * 174 * @param {jQuery} $current 175 * @param {jQuery} $next 176 */ 177 restoreState: function ($current, $next) { 178 $next.css({ 179 'float': 'none', 180 'width': 'auto', 181 }); 182 183 $current.remove(); 184 185 this.$container.width('auto'); 186 } 187 188 }; 189 190 $.fn[pluginName] = function (options) { 191 return this.each(function () { 192 if (!$.data(this, pluginName)) { 193 $.data(this, pluginName, new Plugin(this, options)); 194 } 195 }); 196 }; 197 198 })); 199 200 201 /*! 202 203 Creates a mobile menu based on drilldown.js from Aleksandras Nelkinas 204 205 @name Mobile Menu 206 @author Johannes Grandy 207 @license Do whatever you want 208 209 Copyright (c) 2014 Johannes Grandy 210 211 */ 212 213 214 (function ( $ ) { 215 216 217 // Methods and init 218 219 var methods = { 220 221 init : function( options ) { 222 223 224 // Set settings 225 226 jQuery.fn.mobilemenu.settings = $.extend( {}, jQuery.fn.mobilemenu.settings, options ); 227 228 229 230 // Get settings 231 232 var settings = jQuery.fn.mobilemenu.settings; 233 234 235 236 // Clone the menu 237 238 var target = this.clone(); 239 240 241 242 // Prepare the target with aditional classes 243 244 target.addClass( settings.namespace + '_drilldownmenu' ).find( 'li' ).each( function() { 245 246 var drli = jQuery( this ); 247 var drul = drli.children( 'ul' ); 248 var drxt = drli.children( 'a' ).text(); 249 var drxa = drli.children( 'a' ).attr( 'href' ); 250 251 drul.addClass( settings.namespace + '_drilldownsubmenu' ).hide(); 252 253 if( drul.length > 0 ) { 254 255 drli.addClass( settings.namespace + '_drilldowndeeper' ); 256 257 if( settings.cloneParents ) { 258 259 drul.prepend( '<li class="' + settings.namespace + '_drilldownparent"><a href="' + drxa + '">' + drxt + '</a></li>' ); 260 261 } 262 263 jQuery( '<li class="' + settings.namespace + '_drilldownback" style="position: relative;"><a href="#">' + settings.drilldownBack + '</a></li>' ).prependTo( drul ); 264 265 } 266 267 } ); 268 269 270 271 // Place DOM elements 272 273 var overlay = jQuery( '<div class="' + settings.namespace + '_overlay"></div>').appendTo( 'body' ); 274 275 var menu = jQuery('<div class="' + settings.namespace + '_menucontainer"></div>').appendTo( 'body' ); 276 277 var menuInner = jQuery('<div class="' + settings.namespace + '_menuinner"></div>').appendTo( menu ); 278 279 var drilldown = jQuery('<div class="' + settings.namespace + '_drilldowncontainer"></div>').appendTo( menuInner ); 280 281 var drilldownInner = jQuery('<div class="' + settings.namespace + '_drilldowninner"></div>').appendTo( drilldown ); 282 283 target.appendTo( drilldownInner ); 284 285 286 287 // Fire Aleksandras drilldown script 288 289 drilldown.drilldown({ 290 291 event: 'click', 292 selector: 'a', 293 speed: settings.drilldownAnimationSpeed, 294 cssClass: { 295 296 container: settings.namespace + '_drilldowninner', 297 root: settings.namespace + '_drilldownmenu', 298 sub: settings.namespace + '_drilldownsubmenu', 299 back: settings.namespace + '_drilldownback' 300 301 } 302 303 }); 304 305 306 307 // Close on overlay click 308 309 overlay.on( 'click', function( event ) { 310 311 fvw.hash.remove(); 312 313 } ); 314 315 316 // // Close on link click in the mobilemenu 317 318 // jQuery( document ).on( 'click', '.' + settings.namespace + '_menucontainer a', function( event ) { 319 320 // var li = jQuery( this ).parents( 'li' ); 321 322 // if( settings.closeOnLink && !li.hasClass( settings.namespace + '_drilldowndeeper' ) && !li.hasClass( settings.namespace + '_drilldownback' ) ) { 323 324 // jQuery.fn.mobilemenu( 'close' ); 325 326 // } 327 328 // } ); 329 330 331 // Listen for hashchanges 332
333 jQuery( window ).bind( 'hashchange load', function( e ) { 334 335 if( fvw.hash.beginsWidth( 'mobilemenu' ) ) { 336 337 jQuery.fn.mobilemenu( 'open' ); 338 339 } else { 340 341 jQuery.fn.mobilemenu( 'close' ); 342 343 } 344 345 } ); 346 347 348 settings.onCreate( settings ); 349 350 351 352 }, 353 354 open: function() { 355 356 var settings = jQuery.fn.mobilemenu.settings; 357 358 jQuery( 'body' ).addClass( settings.namespace + '_active' ); 359 360 settings.onOpen( this, settings ); 361 362 }, 363 364 close: function() { 365 366 var settings = jQuery.fn.mobilemenu.settings; 367 368 jQuery( 'body' ).removeClass( settings.namespace + '_active' ); 369 370 settings.onClose( this, settings ); 371 372 } 373 374 }; 375 376 377 // The plugin caller 378 379 jQuery.fn.mobilemenu = function( methodOrOptions ) { 380 381 if ( methods[methodOrOptions] ) { 382 383 return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ) ); 384 385 } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { 386 387 return methods.init.apply( this, arguments ); 388 389 } else { 390 391 jQuery.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.mobilemenu' ); 392 393 } 394 395 }; 396 397 398 // Settings default 399 400 jQuery.fn.mobilemenu.settings = { 401 402 namespace: 'mobilemenu', // This is the name base for classes in the menu 403 404 closeOnLink: true, // Close if a link inside the menu is clicked 405 cloneParents: true, // The menu items with submenu are not clickable (because they trigger the deeper slide). Change this if this menupoints should be cloned as child of theirself 406 407 drilldownBack: 'Back', // Drilldown back text 408 drilldownAnimationSpeed: 130, // Speed of the drilldown hirarchy change 409 410 onCreate: function() {}, 411 onOpen: function() {}, 412 onClose: function() {} 413 414 }; 415 416 417 418 }( jQuery )); 419 420
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.