以下是 jQuery美化Select下拉菜单插件特效代码 的示例演示效果:
部分效果截图:
HTML代码(index.html):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Filament Group Lab</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="fg.menu.js"></script>
<link type="text/css" href="fg.menu.css" media="screen" rel="stylesheet" />
<link type="text/css" href="theme/ui.all.css" media="screen" rel="stylesheet" />
<!-- styles for this example page only -->
<style type="text/css">
body { font-size:62.5%; margin:0; padding:0; }
#menuLog { font-size:1.4em; margin:20px; }
.hidden { position:absolute; top:0; left:-9999px; width:1px; height:1px; overflow:hidden; }
.fg-button { clear:left; margin:0 4px 40px 20px; padding: .4em 1em; text-decoration:none !important; cursor:pointer; position: relative; text-align: center; zoom: 1; }
.fg-button .ui-icon { position: absolute; top: 50%; margin-top: -8px; left: 50%; margin-left: -8px; }
a.fg-button { float:left; }
button.fg-button { width:auto; overflow:visible; } /* removes extra button width in IE */
.fg-button-icon-left { padding-left: 2.1em; }
.fg-button-icon-right { padding-right: 2.1em; }
.fg-button-icon-left .ui-icon { right: auto; left: .2em; margin-left: 0; }
.fg-button-icon-right .ui-icon { left: auto; right: .2em; margin-left: 0; }
.fg-button-icon-solo { display:block; width:8px; text-indent: -9999px; } /* solo icon buttons must have block properties for the text-indent to work */
.fg-button.ui-state-loading .ui-icon { background: url(spinner_bar.gif) no-repeat 0 0; }
</style>
<!-- style exceptions for IE 6 -->
<!--[if IE 6]>
<style type="text/css">
.fg-menu-ipod .fg-menu li { width: 95%; }
.fg-menu-ipod .ui-widget-content { border:0; }
</style>
<![endif]-->
<script type="text/javascript">
$(function(){
// BUTTONS
$('.fg-button').hover(
function(){ $(this).removeClass('ui-state-default').addClass('ui-state-focus'); },
function(){ $(this).removeClass('ui-state-focus').addClass('ui-state-default'); }
);
// MENUS
$('#flat').menu({
content: $('#flat').next().html(), // grab content from this page
showSpeed: 400
});
$('#hierarchy').menu({
content: $('#hierarchy').next().html(),
crumbDefaultText: ' '
});
$('#hierarchybreadcrumb').menu({
content: $('#hierarchybreadcrumb').next().html(),
backLink: false
});
// or from an external source
$.get('menuContent.html', function(data){ // grab content from another page
$('#flyout').menu({ content: data, flyOut: true });
});
});
</script>
<!-- theme switcher button -->
<script type="text/javascript" src="http://ui.jquery.com/applications/themeroller/themeswitchertool/"></script>
<script type="text/javascript"> $(function(){ $('<div style="position: absolute; top: 20px; right: 300px;" />').appendTo('body').themeswitcher(); }); </script>
</head>
<body>
<p id="menuLog">
You chose: <span id="menuSelection"></span></p>
<a tabindex="0" href="#search-engines" class="fg-button fg-button-icon-right ui-widget ui-state-default ui-corner-all" id="flat"><span class="ui-icon ui-icon-triangle-1-s"></span>flat menu</a>
<div id="search-engines" class="hidden">
<ul>
<li><a href="#">Google</a></li>
<li><a href="#">Yahoo</a></li>
<li><a href="#">MSN</a></li>
<li><a href="#">Ask</a></li>
<li><a href="#">AOL</a></li>
</ul>
</div>
<a tabindex="0" href="menuContent.html" class="fg-button fg-button-icon-right ui-widget ui-state-default ui-corner-all" id="flyout"><span class="ui-icon ui-icon-triangle-1-s"></span>flyout menu</a>
<a tabindex="0" href="#news-items" class="fg-button fg-button-icon-right ui-widget ui-state-default ui-corner-all" id="hierarchy"><span class="ui-icon ui-icon-triangle-1-s"></span>ipod-style menu</a>
<div id="news-items" class="hidden">
<ul>
<li><a href="#">Breaking News</a>
<ul>
<li><a href="#">Entertainment</a></li>
<li><a href="http://www.w3schools.com/tags/html5.asp">Politics</a></li>
<li><a href="#">A&E</a></li>
<li><a href="#">Sports</a>
<ul>
<li><a href="#">Baseball</a></li>
<li><a href="#">Basketball</a></li>
<li><a href="#">A really long label would wrap nicely as you can see</a></li>
<li><a href="#">Swimming</a>
<ul>
<li><a href="#">High School</a></li>
<li><a href="#">College</a></li>
<li><a href="#">Professional</a>
<ul>
<li><a href="#">Mens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
<li><a href="#">Womens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan <storng>牛</storng><u>图</u><i>库</i> Site</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Adult Recreational</a></li>
<li><a href="#">Youth Recreational</a></li>
<li><a href="#">Senior Recreational</a></li>
</ul>
</li>
<li><a href="#">Tennis</a></li>
<li><a href="#">Ice Skating</a></li>
<li><a href="#">Javascript <storng>牛</storng><u>图</u><i>库</i> Programming</a></li>
<li><a href="#">Running</a></li>
<li><a href="#">Walking</a></li>
</ul>
</li>
<li><a href="#">Local</a></li>
<li><a href="#">Health</a></li>
</ul>
</li>
<li><a href="#">Entertainment</a>
<ul>
<li><a href="#">Celebrity news</a></li>
<li><a href="#">Gossip</a></li>
<li><a href="#">Movies</a></li>
<li><a href="#">Music</a>
<ul>
<li><a href="#">Alternative</a></li>
<li><a href="#">Country</a></li>
<li><a href="#">Dance</a></li>
<li><a href="#">Electronica</a></li>
<li><a href="#">Metal</a></li>
<li><a href="#">Pop</a></li>
<li><a href="#">Rock</a>
<ul>
<li><a href="#">Bands</a>
<ul>
<li><a href="#">Dokken</a></li>
</ul>
</li>
<li><a href="#">Fan Clubs</a></li>
<li><a href="#">Songs</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Slide shows</a></li>
<li><a href="#">Red carpet</a></li>
</ul>
</li>
<li><a href="#">Finance</a>
<ul>
<li><a href="#">Personal</a>
<ul>
<li><a href="#">Loans</a></li>
<li><a href="#">Savings</a></li>
<li><a href="#">Mortgage</a></li>
<li><a href="#">Debt</a></li>
</ul>
</li>
<li><a href="#">Business</a></li>
</ul>
</li>
<li><a href="#">Food & Cooking</a>
<ul>
<li><a href="#">Breakfast</a></li>
<li><a href="#">Lunch</a></li>
<li><a href="#">Dinner</a></li>
<li><a href="#">Dessert</a>
<ul>
<li><a href="#">Dump Cake</a></li>
<li><a href="#">Doritos</a></li>
<li><a href="#">Both please.</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Lifestyle</a></li>
<li><a href="#">News</a></li>
<li><a href="#">Politics</a></li>
<li><a href="#">Sports</a>
<ul>
<li><a href="#">Baseball</a></li>
<li><a href="#">Basketball</a></li>
<li><a href="#">Swimming</a>
<ul>
<li><a href="#">High School</a></li>
<li><a href="#">College</a></li>
<li><a href="#">Professional</a>
<ul>
<li><a href="#">Mens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
<li><a href="#">Womens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Adult Recreational</a></li>
<li><a href="#">Youth Recreational</a></li>
<li><a href="#">Senior Recreational</a></li>
</ul>
</li>
<li><a href="#">Tennis</a></li>
<li><a href="#">Ice Skating</a></li>
<li><a href="#">Javascript Programming</a></li>
<li><a href="#">Running</a></li>
<li><a href="#">Walking</a></li>
</ul>
</li>
</ul>
</div>
<a tabindex="0" href="#news-items-2" class="fg-button fg-button-icon-right ui-widget ui-state-default ui-corner-all" id="hierarchybreadcrumb"><span class="ui-icon ui-icon-triangle-1-s"></span>ipod-style menu w/ breadcrumb</a>
<div id="news-items-2" class="hidden">
<ul>
<li><a href="#">Breaking News</a>
<ul>
<li><a href="#">Entertainment</a></li>
<li><a href="#">Politics</a></li>
<li><a href="#">A&E</a></li>
<li><a href="#">Sports</a>
<ul>
<li><a href="#">Baseball</a></li>
<li><a href="#">Basketball</a></li>
<li><a href="#">A really long label would wrap nicely as you can see</a></li>
<li><a href="#">Swimming</a>
<ul>
<li><a href="#">High School</a></li>
<li><a href="#">College</a></li>
<li><a href="#">Professional</a>
<ul>
<li><a href="#">Mens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
<li><a href="#">Womens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Adult Recreational</a></li>
<li><a href="#">Youth Recreational</a></li>
<li><a href="#">Senior Recreational</a></li>
</ul>
</li>
<li><a href="#">Tennis</a></li>
<li><a href="#">Ice Skating</a></li>
<li><a href="#">Javascript Programming</a></li>
<li><a href="#">Running</a></li>
<li><a href="#">Walking</a></li>
</ul>
</li>
<li><a href="#">Local</a></li>
<li><a href="#">Health</a></li>
</ul>
</li>
<li><a href="#">Entertainment</a>
<ul>
<li><a href="#">Celebrity news</a></li>
<li><a href="#">Gossip</a></li>
<li><a href="#">Movies</a></li>
<li><a href="#">Music</a>
<ul>
<li><a href="#">Alternative</a></li>
<li><a href="#">Country</a></li>
<li><a href="#">Dance</a></li>
<li><a href="#">Electronica</a></li>
<li><a href="#">Metal</a></li>
<li><a href="#">Pop</a></li>
<li><a href="#">Rock</a>
<ul>
<li><a href="#">Bands</a>
<ul>
<li><a href="#">Dokken</a></li>
</ul>
</li>
<li><a href="#">Fan Clubs</a></li>
<li><a href="#">Songs</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Slide shows</a></li>
<li><a href="#">Red carpet</a></li>
</ul>
</li>
<li><a href="#">Finance</a>
<ul>
<li><a href="#">Personal</a>
<ul>
<li><a href="#">Loans</a></li>
<li><a href="#">Savings</a></li>
<li><a href="#">Mortgage</a></li>
<li><a href="#">Debt</a></li>
</ul>
</li>
<li><a href="#">Business</a></li>
</ul>
</li>
<li><a href="#">Food & Cooking</a>
<ul>
<li><a href="#">Breakfast</a></li>
<li><a href="#">Lunch</a></li>
<li><a href="#">Dinner</a></li>
<li><a href="#">Dessert</a>
<ul>
<li><a href="#">Dump Cake</a></li>
<li><a href="#">Doritos</a></li>
<li><a href="#">Both please.</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Lifestyle</a></li>
<li><a href="#">News</a></li>
<li><a href="#">Politics</a></li>
<li><a href="#">Sports</a>
<ul>
<li><a href="#">Baseball</a></li>
<li><a href="#">Basketball</a></li>
<li><a href="#">Swimming</a>
<ul>
<li><a href="#">High School</a></li>
<li><a href="#">College</a></li>
<li><a href="#">Professional</a>
<ul>
<li><a href="#">Mens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
<li><a href="#">Womens Swimming</a>
<ul>
<li><a href="#">News</a></li>
<li><a href="#">Events</a></li>
<li><a href="#">Awards</a></li>
<li><a href="#">Schedule</a></li>
<li><a href="#">Team Members</a></li>
<li><a href="#">Fan Site</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#">Adult Recreational</a></li>
<li><a href="#">Youth Recreational</a></li>
<li><a href="#">Senior Recreational</a></li>
</ul>
</li>
<li><a href="#">Tennis</a></li>
<li><a href="#">Ice Skating</a></li>
<li><a href="#">Javascript Programming</a></li>
<li><a href="#">Running</a></li>
<li><a href="#">Walking</a></li>
</ul>
</li>
</ul>
</div>
</body>
</html>
JS代码(fg.menu.js):
/*--------------------------------------------------------------------Scripts for creating and manipulating custom menus based on standard <ul> markupVersion:3.0,03.31.2009By:Maggie Costello Wachs (maggie@filamentgroup.com) and Scott Jehl (scott@filamentgroup.com)http://www.filamentgroup.com* reference articles:http://www.filamentgroup.com/lab/jquery_ipod_style_drilldown_menu/Copyright (c) 2009 Filament GroupDual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.--------------------------------------------------------------------*/
var allUIMenus = [];
$.fn.menu = function(options){
var caller = this;
var options = options;
var m = new Menu(caller,options);
allUIMenus.push(m);
$(this).mousedown(function(){
if (!m.menuOpen){
m.showLoading();
}
;
}
).click(function(){
if (m.menuOpen == false){
m.showMenu();
}
else{
m.kill();
}
;
return false;
}
);
}
;
function Menu(caller,options){
var menu = this;
var caller = $(caller);
var container = $('<div class="fg-menu-container ui-widget ui-widget-content ui-corner-all">'+options.content+'</div>');
this.menuOpen = false;
this.menuExists = false;
var options = jQuery.extend({
content:null,width:180,// width of menu container,must be set or passed in to calculate widths of child menusmaxHeight:180,// max height of menu (if a drilldown:height does not include breadcrumb)positionOpts:{
posX:'left',posY:'bottom',offsetX:0,offsetY:0,directionH:'right',directionV:'down',detectH:true,// do horizontal collision detectiondetectV:true,// do vertical collision detectionlinkToFront:false}
,showSpeed:200,// show/hide speed in millisecondscallerOnState:'ui-state-active',// class to change the appearance of the link/button when the menu is showingloadingState:'ui-state-loading',// class added to the link/button while the menu is createdlinkHover:'ui-state-hover',// class for menu option hover statelinkHoverSecondary:'li-hover',// alternate class,may be used for multi-level menus// ----- multi-level menu defaults -----crossSpeed:200,// cross-fade speed for multi-level menuscrumbDefaultText:'Choose an option:',backLink:true,// in the ipod-style menu:instead of breadcrumbs,show only a 'back' linkbackLinkText:'Back',flyOut:false,// multi-level menus are ipod-style by default;
this parameter overrides to make a flyout insteadflyOutOnState:'ui-state-default',nextMenuLink:'ui-icon-triangle-1-e',// class to style the link (specifically,a span within the link) used in the multi-level menu to show the next leveltopLinkText:'All',nextCrumbLink:'ui-icon-carat-1-e'}
,options);
var killAllMenus = function(){
$.each(allUIMenus,function(i){
if (allUIMenus[i].menuOpen){
allUIMenus[i].kill();
}
;
}
);
}
;
this.kill = function(){
caller.removeClass(options.loadingState).removeClass('fg-menu-open').removeClass(options.callerOnState);
container.find('li').removeClass(options.linkHoverSecondary).find('a').removeClass(options.linkHover);
if (options.flyOutOnState){
container.find('li a').removeClass(options.flyOutOnState);
}
;
if (options.callerOnState){
caller.removeClass(options.callerOnState);
}
;
if (container.is('.fg-menu-ipod')){
menu.resetDrilldownMenu();
}
;
if (container.is('.fg-menu-flyout')){
menu.resetFlyoutMenu();
}
;
container.parent().hide();
menu.menuOpen = false;
$(document).unbind('click',killAllMenus);
$(document).unbind('keydown');
}
;
this.showLoading = function(){
caller.addClass(options.loadingState);
}
;
this.showMenu = function(){
killAllMenus();
if (!menu.menuExists){
menu.create()}
;
caller.addClass('fg-menu-open').addClass(options.callerOnState);
container.parent().show().click(function(){
menu.kill();
return false;
}
);
container.hide().slideDown(options.showSpeed).find('.fg-menu:eq(0)');
menu.menuOpen = true;
caller.removeClass(options.loadingState);
$(document).click(killAllMenus);
// assign key events$(document).keydown(function(event){
var e;
if (event.which !=""){
e = event.which;
}
else if (event.charCode != ""){
e = event.charCode;
}
else if (event.keyCode != ""){
e = event.keyCode;
}
var menuType = ($(event.target).parents('div').is('.fg-menu-flyout')) ? 'flyout':'ipod';
switch(e){
case 37:// left arrowif (menuType == 'flyout'){
$(event.target).trigger('mouseout');
if ($('.'+options.flyOutOnState).size() > 0){
$('.'+options.flyOutOnState).trigger('mouseover');
}
;
}
;
if (menuType == 'ipod'){
$(event.target).trigger('mouseout');
if ($('.fg-menu-footer').find('a').size() > 0){
$('.fg-menu-footer').find('a').trigger('click');
}
;
if ($('.fg-menu-header').find('a').size() > 0){
$('.fg-menu-current-crumb').prev().find('a').trigger('click');
}
;
if ($('.fg-menu-current').prev().is('.fg-menu-indicator')){
$('.fg-menu-current').prev().trigger('mouseover');
}
;
}
;
return false;
break;
case 38:// up arrowif ($(event.target).is('.' + options.linkHover)){
var prevLink = $(event.target).parent().prev().find('a:eq(0)');
if (prevLink.size() > 0){
$(event.target).trigger('mouseout');
prevLink.trigger('mouseover');
}
;
}
else{
container.find('a:eq(0)').trigger('mouseover');
}
return false;
break;
case 39:// right arrowif ($(event.target).is('.fg-menu-indicator')){
if (menuType == 'flyout'){
$(event.target).next().find('a:eq(0)').trigger('mouseover');
}
else if (menuType == 'ipod'){
$(event.target).trigger('click');
setTimeout(function(){
$(event.target).next().find('a:eq(0)').trigger('mouseover');
}
,options.crossSpeed);
}
;
}
;
return false;
break;
case 40:// down arrowif ($(event.target).is('.' + options.linkHover)){
var nextLink = $(event.target).parent().next().find('a:eq(0)');
if (nextLink.size() > 0){
$(event.target).trigger('mouseout');
nextLink.trigger('mouseover');
}
;
}
else{
container.find('a:eq(0)').trigger('mouseover');
}
return false;
break;
case 27:// escapekillAllMenus();
break;
case 13:// enterif ($(event.target).is('.fg-menu-indicator') && menuType == 'ipod'){
$(event.target).trigger('click');
setTimeout(function(){
$(event.target).next().find('a:eq(0)').trigger('mouseover');
}
,options.crossSpeed);
}
;
break;
}
;
}
);
}
;
this.create = function(){
container.css({
width:options.width}
).appendTo('body').find('ul:first').not('.fg-menu-breadcrumb').addClass('fg-menu');
container.find('ul,li a').addClass('ui-corner-all');
// aria roles & attributescontainer.find('ul').attr('role','menu').eq(0).attr('aria-activedescendant','active-menuitem').attr('aria-labelledby',caller.attr('id'));
container.find('li').attr('role','menuitem');
container.find('li:has(ul)').attr('aria-haspopup','true').find('ul').attr('aria-expanded','false');
container.find('a').attr('tabindex','-1');
// when there are multiple levels of hierarchy,create flyout or drilldown menuif (container.find('ul').size() > 1){
if (options.flyOut){
menu.flyout(container,options);
}
else{
menu.drilldown(container,options);
}
}
else{
container.find('a').click(function(){
menu.chooseItem(this);
return false;
}
);
}
;
if (options.linkHover){
var allLinks = container.find('.fg-menu li a');
allLinks.hover(function(){
var menuitem = $(this);
$('.'+options.linkHover).removeClass(options.linkHover).blur().parent().removeAttr('id');
$(this).addClass(options.linkHover).focus().parent().attr('id','active-menuitem');
}
,function(){
$(this).removeClass(options.linkHover).blur().parent().removeAttr('id');
}
);
}
;
if (options.linkHoverSecondary){
container.find('.fg-menu li').hover(function(){
$(this).siblings('li').removeClass(options.linkHoverSecondary);
if (options.flyOutOnState){
$(this).siblings('li').find('a').removeClass(options.flyOutOnState);
}
$(this).addClass(options.linkHoverSecondary);
}
,function(){
$(this).removeClass(options.linkHoverSecondary);
}
);
}
;
menu.setPosition(container,caller,options);
menu.menuExists = true;
}
;
this.chooseItem = function(item){
menu.kill();
// edit this for your own custom function/callback:$('#menuSelection').text($(item).text());
location.href = $(item).attr('href');
}
;
}
;
Menu.prototype.flyout = function(container,options){
var menu = this;
this.resetFlyoutMenu = function(){
var allLists = container.find('ul ul');
allLists.removeClass('ui-widget-content').hide();
}
;
container.addClass('fg-menu-flyout').find('li:has(ul)').each(function(){
var linkWidth = container.width();
var showTimer,hideTimer;
var allSubLists = $(this).find('ul');
allSubLists.css({
left:linkWidth,width:linkWidth}
).hide();
$(this).find('a:eq(0)').addClass('fg-menu-indicator').html('<span>' + $(this).find('a:eq(0)').text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>').hover(function(){
clearTimeout(hideTimer);
var subList = $(this).next();
if (!fitVertical(subList,$(this).offset().top)){
subList.css({
top:'auto',bottom:0}
);
}
;
if (!fitHorizontal(subList,$(this).offset().left + 100)){
subList.css({
left:'auto',right:linkWidth,'z-index':999}
);
}
;
showTimer = setTimeout(function(){
subList.addClass('ui-widget-content').show(options.showSpeed).attr('aria-expanded','true');
}
,300);
}
,function(){
clearTimeout(showTimer);
var subList = $(this).next();
hideTimer = setTimeout(function(){
subList.removeClass('ui-widget-content').hide(options.showSpeed).attr('aria-expanded','false');
}
,400);
}
);
$(this).find('ul a').hover(function(){
clearTimeout(hideTimer);
if ($(this).parents('ul').prev().is('a.fg-menu-indicator')){
$(this).parents('ul').prev().addClass(options.flyOutOnState);
}
}
,function(){
hideTimer = setTimeout(function(){
allSubLists.hide(options.showSpeed);
container.find(options.flyOutOnState).removeClass(options.flyOutOnState);
}
,500);
}
);
}
);
container.find('a').click(function(){
menu.chooseItem(this);
return false;
}
);
}
;
Menu.prototype.drilldown = function(container,options){
var menu = this;
var topList = container.find('.fg-menu');
var breadcrumb = $('<ul class="fg-menu-breadcrumb ui-widget-header ui-corner-all ui-helper-clearfix"></ul>');
var crumbDefaultHeader = $('<li class="fg-menu-breadcrumb-text">'+options.crumbDefaultText+'</li>');
var firstCrumbText = (options.backLink) ? options.backLinkText:options.topLinkText;
var firstCrumbClass = (options.backLink) ? 'fg-menu-prev-list':'fg-menu-all-lists';
var firstCrumbLinkClass = (options.backLink) ? 'ui-state-default ui-corner-all':'';
var firstCrumbIcon = (options.backLink) ? '<span class="ui-icon ui-icon-triangle-1-w"></span>':'';
var firstCrumb = $('<li class="'+firstCrumbClass+'"><a href="#" class="'+firstCrumbLinkClass+'">'+firstCrumbIcon+firstCrumbText+'</a></li>');
container.addClass('fg-menu-ipod');
if (options.backLink){
breadcrumb.addClass('fg-menu-footer').appendTo(container).hide();
}
else{
breadcrumb.addClass('fg-menu-header').prependTo(container);
}
;
breadcrumb.append(crumbDefaultHeader);
var checkMenuHeight = function(el){
if (el.height() > options.maxHeight){
el.addClass('fg-menu-scroll')}
;
el.css({
height:options.maxHeight}
);
}
;
var resetChildMenu = function(el){
el.removeClass('fg-menu-scroll').removeClass('fg-menu-current').height('auto');
}
;
this.resetDrilldownMenu = function(){
$('.fg-menu-current').removeClass('fg-menu-current');
topList.animate({
left:0}
,options.crossSpeed,function(){
$(this).find('ul').each(function(){
$(this).hide();
resetChildMenu($(this));
}
);
topList.addClass('fg-menu-current');
}
);
$('.fg-menu-all-lists').find('span').remove();
breadcrumb.empty().append(crumbDefaultHeader);
$('.fg-menu-footer').empty().hide();
checkMenuHeight(topList);
}
;
topList.addClass('fg-menu-content fg-menu-current ui-widget-content ui-helper-clearfix').css({
width:container.width()}
).find('ul').css({
width:container.width(),left:container.width()}
).addClass('ui-widget-content').hide();
checkMenuHeight(topList);
topList.find('a').each(function(){
// if the link opens a child menu:if ($(this).next().is('ul')){
$(this).addClass('fg-menu-indicator').each(function(){
$(this).html('<span>' + $(this).text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>');
}
).click(function(){
// ----- show the next menuvar nextList = $(this).next();
var parentUl = $(this).parents('ul:eq(0)');
var parentLeft = (parentUl.is('.fg-menu-content')) ? 0:parseFloat(topList.css('left'));
var nextLeftVal = Math.round(parentLeft - parseFloat(container.width()));
var footer = $('.fg-menu-footer');
// show next menuresetChildMenu(parentUl);
checkMenuHeight(nextList);
topList.animate({
left:nextLeftVal}
,options.crossSpeed);
nextList.show().addClass('fg-menu-current').attr('aria-expanded','true');
var setPrevMenu = function(backlink){
var b = backlink;
var c = $('.fg-menu-current');
var prevList = c.parents('ul:eq(0)');
c.hide().attr('aria-expanded','false');
resetChildMenu(c);
checkMenuHeight(prevList);
prevList.addClass('fg-menu-current').attr('aria-expanded','true');
if (prevList.hasClass('fg-menu-content')){
b.remove();
footer.hide();
}
;
}
;
// initialize "back" linkif (options.backLink){
if (footer.find('a').size() == 0){
footer.show();
$('<a href="#"><span class="ui-icon ui-icon-triangle-1-w"></span> <span>Back</span></a>').appendTo(footer).click(function(){
// ----- show the previous menuvar b = $(this);
var prevLeftVal = parseFloat(topList.css('left')) + container.width();
topList.animate({
left:prevLeftVal}
,options.crossSpeed,function(){
setPrevMenu(b);
}
);
return false;
}
);
}
}
// or initialize top breadcrumbelse{
if (breadcrumb.find('li').size() == 1){
breadcrumb.empty().append(firstCrumb);
firstCrumb.find('a').click(function(){
menu.resetDrilldownMenu();
return false;
}
);
}
$('.fg-menu-current-crumb').removeClass('fg-menu-current-crumb');
var crumbText = $(this).find('span:eq(0)').text();
var newCrumb = $('<li class="fg-menu-current-crumb"><a href="javascript://" class="fg-menu-crumb">'+crumbText+'</a></li>');
newCrumb.appendTo(breadcrumb).find('a').click(function(){
if ($(this).parent().is('.fg-menu-current-crumb')){
menu.chooseItem(this);
}
else{
var newLeftVal = - ($('.fg-menu-current').parents('ul').size() - 1) * 180;
topList.animate({
left:newLeftVal}
,options.crossSpeed,function(){
setPrevMenu();
}
);
// make this the current crumb,delete all breadcrumbs after this one,and navigate to the relevant menu$(this).parent().addClass('fg-menu-current-crumb').find('span').remove();
$(this).parent().nextAll().remove();
}
;
return false;
}
);
newCrumb.prev().append(' <span class="ui-icon '+options.nextCrumbLink+'"></span>');
}
;
return false;
}
);
}
// if the link is a leaf node (doesn't open a child menu)else{
$(this).click(function(){
menu.chooseItem(this);
return false;
}
);
}
;
}
);
}
;
/* Menu.prototype.setPosition parameters (defaults noted with *):referrer = the link (or other element) used to show the overlaid objectsettings = can override the defaults:- posX/Y:where the top left corner of the object should be positioned in relation to its referrer.X:left*,center,rightY:top,center,bottom*- offsetX/Y:the number of pixels to be offset from the x or y position. Can be a positive or negative number.- directionH/V:where the entire menu should appear in relation to its referrer.Horizontal:left*,rightVertical:up,down*- detectH/V:detect the viewport horizontally / vertically- linkToFront:copy the menu link and place it on top of the menu (visual effect to make it look like it overlaps the object) */
Menu.prototype.setPosition = function(widget,caller,options){
var el = widget;
var referrer = caller;
var dims ={
refX:referrer.offset().left,refY:referrer.offset().top,refW:referrer.getTotalWidth(),refH:referrer.getTotalHeight()}
;
var options = options;
var xVal,yVal;
var helper = $('<div class="positionHelper"></div>');
helper.css({
position:'absolute',left:dims.refX,top:dims.refY,width:dims.refW,height:dims.refH}
);
el.wrap(helper);
// get X posswitch(options.positionOpts.posX){
case 'left':xVal = 0;
break;
case 'center':xVal = dims.refW / 2;
break;
case 'right':xVal = dims.refW;
break;
}
;
// get Y posswitch(options.positionOpts.posY){
case 'top':yVal = 0;
break;
case 'center':yVal = dims.refH / 2;
break;
case 'bottom':yVal = dims.refH;
break;
}
;
// add the offsets (zero by default)xVal += options.positionOpts.offsetX;
yVal += options.positionOpts.offsetY;
// position the object verticallyif (options.positionOpts.directionV == 'up'){
el.css({
top:'auto',bottom:yVal}
);
if (options.positionOpts.detectV && !fitVertical(el)){
el.css({
bottom:'auto',top:yVal}
);
}
}
else{
el.css({
bottom:'auto',top:yVal}
);
if (options.positionOpts.detectV && !fitVertical(el)){
el.css({
top:'auto',bottom:yVal}
);
}
}
;
// and horizontallyif (options.positionOpts.directionH == 'left'){
el.css({
left:'auto',right:xVal}
);
if (options.positionOpts.detectH && !fitHorizontal(el)){
el.css({
right:'auto',left:xVal}
);
}
}
else{
el.css({
right:'auto',left:xVal}
);
if (options.positionOpts.detectH && !fitHorizontal(el)){
el.css({
left:'auto',right:xVal}
);
}
}
;
// if specified,clone the referring element and position it so that it appears on top of the menuif (options.positionOpts.linkToFront){
referrer.clone().addClass('linkClone').css({
position:'absolute',top:0,right:'auto',bottom:'auto',left:0,width:referrer.width(),height:referrer.height()}
).insertAfter(el);
}
;
}
;
/* Utilities to sort and find viewport dimensions */
function sortBigToSmall(a,b){
return b - a;
}
;
jQuery.fn.getTotalWidth = function(){
return $(this).width() + parseInt($(this).css('paddingRight')) + parseInt($(this).css('paddingLeft')) + parseInt($(this).css('borderRightWidth')) + parseInt($(this).css('borderLeftWidth'));
}
;
jQuery.fn.getTotalHeight = function(){
return $(this).height() + parseInt($(this).css('paddingTop')) + parseInt($(this).css('paddingBottom')) + parseInt($(this).css('borderTopWidth')) + parseInt($(this).css('borderBottomWidth'));
}
;
function getScrollTop(){
return self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
}
;
function getScrollLeft(){
return self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
}
;
function getWindowHeight(){
var de = document.documentElement;
return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
}
;
function getWindowWidth(){
var de = document.documentElement;
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
}
;
/* Utilities to test whether an element will fit in the viewportParameters:el = element to position,requiredleftOffset / topOffset = optional parameter if the offset cannot be calculated (i.e.,if the object is in the DOM but is set to display:'none') */
function fitHorizontal(el,leftOffset){
var leftVal = parseInt(leftOffset) || $(el).offset().left;
return (leftVal + $(el).width() <= getWindowWidth() + getScrollLeft() && leftVal - getScrollLeft() >= 0);
}
;
function fitVertical(el,topOffset){
var topVal = parseInt(topOffset) || $(el).offset().top;
return (topVal + $(el).height() <= getWindowHeight() + getScrollTop() && topVal - getScrollTop() >= 0);
}
;
/*-------------------------------------------------------------------- * javascript method:"pxToEm" * by:Scott Jehl (scott@filamentgroup.com) Maggie Wachs (maggie@filamentgroup.com) http://www.filamentgroup.com * * Copyright (c) 2008 Filament Group * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses. * * Description:Extends the native Number and String objects with pxToEm method. pxToEm converts a pixel value to ems depending on inherited font size. * Article:http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/ * Demo:http://www.filamentgroup.com/examples/pxToEm/ * * Options:scope:string or jQuery selector for font-size scopingreverse:Boolean,true reverses the conversion to em-px * Dependencies:jQuery library * Usage Example:myPixelValue.pxToEm();
or myPixelValue.pxToEm({
'scope':'#navigation',reverse:true}
);
* * Version:2.0,08.01.2008 * Changelog:*08.02.2007 initial Version 1.0 *08.01.2008 - fixed font-size calculation for IE--------------------------------------------------------------------*/
Number.prototype.pxToEm = String.prototype.pxToEm = function(settings){
//set defaultssettings = jQuery.extend({
scope:'body',reverse:false}
,settings);
var pxVal = (this == '') ? 0:parseFloat(this);
var scopeVal;
var getWindowWidth = function(){
var de = document.documentElement;
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
}
;
/* When a percentage-based font-size is set on the body,IE returns that percent of the window width as the font-size.For example,if the body font-size is 62.5% and the window width is 1000px,IE will return 625px as the font-size.When this happens,we calculate the correct body font-size (%) and multiply it by 16 (the standard browser font size)to get an accurate em value. */
if (settings.scope == 'body' && $.browser.msie && (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(1) > 0.0){
var calcFontSize = function(){
return (parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(3) * 16;
}
;
scopeVal = calcFontSize();
}
else{
scopeVal = parseFloat(jQuery(settings.scope).css("font-size"));
}
;
var result = (settings.reverse == true) ? (pxVal * scopeVal).toFixed(2) + 'px':(pxVal / scopeVal).toFixed(2) + 'em';
return result;
}
;
CSS代码(fg.menu.css):
/* Styles for jQuery menu widgetAuthor:Maggie Wachs,maggie@filamentgroup.comDate:September 2008*/
/* REQUIRED STYLES - the menus will only render correctly with these rules */
.fg-menu-container{position:absolute;top:0;left:-999px;padding:.4em;overflow:hidden;}
.fg-menu-container.fg-menu-flyout{overflow:visible;}
.fg-menu,.fg-menu ul{list-style-type:none;padding:0;margin:0;}
.fg-menu{position:relative;}
.fg-menu-flyout .fg-menu{position:static;}
.fg-menu ul{position:absolute;top:0;}
.fg-menu ul ul{top:-1px;}
.fg-menu-container.fg-menu-ipod .fg-menu-content,.fg-menu-container.fg-menu-ipod .fg-menu-content ul{background:none !important;}
.fg-menu.fg-menu-scroll,.fg-menu ul.fg-menu-scroll{overflow:scroll;overflow-x:hidden;}
.fg-menu li{clear:both;float:left;width:100%;margin:0;padding:0;border:0;}
.fg-menu li li{font-size:1em;}
/* inner li font size must be reset so that they don't blow up */
.fg-menu-flyout ul ul{padding:.4em;}
.fg-menu-flyout li{position:relative;}
.fg-menu-scroll{overflow:scroll;overflow-x:hidden;}
.fg-menu-breadcrumb{margin:0;padding:0;}
.fg-menu-footer{margin-top:.4em;padding:.4em;}
.fg-menu-header{margin-bottom:.4em;padding:.4em;}
.fg-menu-breadcrumb li{float:left;list-style:none;margin:0;padding:0 .2em;font-size:.9em;opacity:.7;}
.fg-menu-breadcrumb li.fg-menu-prev-list,.fg-menu-breadcrumb li.fg-menu-current-crumb{clear:left;float:none;opacity:1;}
.fg-menu-breadcrumb li.fg-menu-current-crumb{padding-top:.2em;}
.fg-menu-breadcrumb a,.fg-menu-breadcrumb span{float:left;}
.fg-menu-footer a:link,.fg-menu-footer a:visited{float:left;width:100%;text-decoration:none;}
.fg-menu-footer a:hover,.fg-menu-footer a:active{}
.fg-menu-footer a span{float:left;cursor:pointer;}
.fg-menu-breadcrumb .fg-menu-prev-list a:link,.fg-menu-breadcrumb .fg-menu-prev-list a:visited,.fg-menu-breadcrumb .fg-menu-prev-list a:hover,.fg-menu-breadcrumb .fg-menu-prev-list a:active{background-image:none;text-decoration:none;}
.fg-menu-breadcrumb .fg-menu-prev-list a{float:left;padding-right:.4em;}
.fg-menu-breadcrumb .fg-menu-prev-list a .ui-icon{float:left;}
.fg-menu-breadcrumb .fg-menu-current-crumb a:link,.fg-menu-breadcrumb .fg-menu-current-crumb a:visited,.fg-menu-breadcrumb .fg-menu-current-crumb a:hover,.fg-menu-breadcrumb .fg-menu-current-crumb a:active{display:block;background-image:none;font-size:1.3em;text-decoration:none;}
/* REQUIRED LINK STYLES:links are "display:block" by default;if the menu options are split intoselectable node links and 'next' links,the script floats the node links left and floats the 'next' links to the right*/
.fg-menu a:link,.fg-menu a:visited,.fg-menu a:hover,.fg-menu a:active{float:left;width:92%;padding:.3em 3%;text-decoration:none;outline:0 !important;}
.fg-menu a{border:1px dashed transparent;}
.fg-menu a.ui-state-default:link,.fg-menu a.ui-state-default:visited,.fg-menu a.ui-state-default:hover,.fg-menu a.ui-state-default:active,.fg-menu a.ui-state-hover:link,.fg-menu a.ui-state-hover:visited,.fg-menu a.ui-state-hover:hover,.fg-menu a.ui-state-hover:active,.fg-menu a.ui-state-active:link,.fg-menu a.ui-state-active:visited,.fg-menu a.ui-state-active:hover,.fg-menu a.ui-state-active:active{border-style:solid;font-weight:normal;}
.fg-menu a span{display:block;cursor:pointer;}
/* SUGGESTED STYLES - for use with jQuery UI Themeroller CSS */
.fg-menu-indicator span{float:left;}
.fg-menu-indicator span.ui-icon{float:right;}
.fg-menu-content.ui-widget-content,.fg-menu-content ul.ui-widget-content{border:0;}
/* ICONS AND DIVIDERS */
.fg-menu.fg-menu-has-icons a:link,.fg-menu.fg-menu-has-icons a:visited,.fg-menu.fg-menu-has-icons a:hover,.fg-menu.fg-menu-has-icons a:active{padding-left:20px;}
.fg-menu .horizontal-divider hr,.fg-menu .horizontal-divider span{padding:0;margin:5px .6em;}
.fg-menu .horizontal-divider hr{border:0;height:1px;}
.fg-menu .horizontal-divider span{font-size:.9em;text-transform:uppercase;padding-left:.2em;}