| /* |
| * jdMenu 1.4.1 (2008-03-31) |
| * |
| * Copyright (c) 2006,2007 Jonathan Sharp (http://jdsharp.us) |
| * Dual licensed under the MIT (MIT-LICENSE.txt) |
| * and GPL (GPL-LICENSE.txt) licenses. |
| * |
| * http://jdsharp.us/ |
| * |
| * Built upon jQuery 1.2.1 (http://jquery.com) |
| * This also requires the jQuery dimensions >= 1.2 plugin |
| */ |
| |
| // This initializes the menu |
| $(function() { |
| $('ul.jd_menu').jdMenu(); |
| }); |
| |
| (function($){ |
| function addEvents(ul) { |
| var settings = $.data( $(ul).parents().andSelf().filter('ul.jd_menu')[0], 'jdMenuSettings' ); |
| $('> li', ul) |
| .bind('mouseenter.jdmenu mouseleave.jdmenu', function(evt) { |
| $(this).toggleClass('jdm_hover'); |
| var ul = $('> ul', this); |
| if ( ul.length == 1 ) { |
| clearTimeout( this.$jdTimer ); |
| var enter = ( evt.type == 'mouseenter' ); |
| var fn = ( enter ? showMenu : hideMenu ); |
| this.$jdTimer = setTimeout(function() { |
| fn( ul[0], settings.onAnimate, settings.isVertical ); |
| }, enter ? settings.showDelay : settings.hideDelay ); |
| } |
| }) |
| .bind('click.jdmenu', function(evt) { |
| var ul = $('> ul', this); |
| if ( ul.length == 1 && |
| ( settings.disableLinks == true || $(this).hasClass('accessible') ) ) { |
| showMenu( ul, settings.onAnimate, settings.isVertical ); |
| return false; |
| } |
| |
| // The user clicked the li and we need to trigger a click for the a |
| if ( evt.target == this ) { |
| var link = $('> a', evt.target).not('.accessible'); |
| if ( link.length > 0 ) { |
| var a = link[0]; |
| if ( !a.onclick ) { |
| window.open( a.href, a.target || '_self' ); |
| } else { |
| $(a).trigger('click'); |
| } |
| } |
| } |
| if ( settings.disableLinks || |
| ( !settings.disableLinks && !$(this).parent().hasClass('jd_menu') ) ) { |
| $(this).parent().jdMenuHide(); |
| evt.stopPropagation(); |
| } |
| }) |
| .find('> a') |
| .bind('focus.jdmenu blur.jdmenu', function(evt) { |
| var p = $(this).parents('li:eq(0)'); |
| if ( evt.type == 'focus' ) { |
| p.addClass('jdm_hover'); |
| } else { |
| p.removeClass('jdm_hover'); |
| } |
| }) |
| .filter('.accessible') |
| .bind('click.jdmenu', function(evt) { |
| evt.preventDefault(); |
| }); |
| } |
| |
| function showMenu(ul, animate, vertical) { |
| var ul = $(ul); |
| if ( ul.is(':visible') ) { |
| return; |
| } |
| ul.bgiframe(); |
| var li = ul.parent(); |
| ul .trigger('jdMenuShow') |
| .positionBy({ target: li[0], |
| targetPos: ( vertical === true || !li.parent().hasClass('jd_menu') ? 1 : 3 ), |
| elementPos: 0, |
| hideAfterPosition: true |
| }); |
| if ( !ul.hasClass('jdm_events') ) { |
| ul.addClass('jdm_events'); |
| addEvents(ul); |
| } |
| li .addClass('jdm_active') |
| // Hide any adjacent menus |
| .siblings('li').find('> ul:eq(0):visible') |
| .each(function(){ |
| hideMenu( this ); |
| }); |
| if ( animate === undefined ) { |
| ul.show(); |
| } else { |
| animate.apply( ul[0], [true] ); |
| } |
| } |
| |
| function hideMenu(ul, animate) { |
| var ul = $(ul); |
| $('.bgiframe', ul).remove(); |
| ul .filter(':not(.jd_menu)') |
| .find('> li > ul:eq(0):visible') |
| .each(function() { |
| hideMenu( this ); |
| }) |
| .end(); |
| if ( animate === undefined ) { |
| ul.hide() |
| } else { |
| animate.apply( ul[0], [false] ); |
| } |
| |
| ul .trigger('jdMenuHide') |
| .parents('li:eq(0)') |
| .removeClass('jdm_active jdm_hover') |
| .end() |
| .find('> li') |
| .removeClass('jdm_active jdm_hover'); |
| } |
| |
| // Public methods |
| $.fn.jdMenu = function(settings) { |
| // Future settings: activateDelay |
| var settings = $.extend({ // Time in ms before menu shows |
| showDelay: 200, |
| // Time in ms before menu hides |
| hideDelay: 500, |
| // Should items that contain submenus not |
| // respond to clicks |
| disableLinks: true |
| // This callback allows for you to animate menus |
| //onAnimate: null |
| }, settings); |
| if ( !$.isFunction( settings.onAnimate ) ) { |
| settings.onAnimate = undefined; |
| } |
| return this.filter('ul.jd_menu').each(function() { |
| $.data( this, |
| 'jdMenuSettings', |
| $.extend({ isVertical: $(this).hasClass('jd_menu_vertical') }, settings) |
| ); |
| addEvents(this); |
| }); |
| }; |
| |
| $.fn.jdMenuUnbind = function() { |
| $('ul.jdm_events', this) |
| .unbind('.jdmenu') |
| .find('> a').unbind('.jdmenu'); |
| }; |
| $.fn.jdMenuHide = function() { |
| return this.filter('ul').each(function(){ |
| hideMenu( this ); |
| }); |
| }; |
| |
| // Private methods and logic |
| $(window) |
| // Bind a click event to hide all visible menus when the document is clicked |
| .bind('click.jdmenu', function(){ |
| $('ul.jd_menu ul:visible').jdMenuHide(); |
| }); |
| })(jQuery); |