📄 jscookmenu.js
字号:
// default node properties
var _cmNodeProperties =
{
// theme prefix
prefix: '',
// main menu display attributes
//
// Note. When the menu bar is horizontal,
// mainFolderLeft and mainFolderRight are
// put in <span></span>. When the menu
// bar is vertical, they would be put in
// a separate TD cell.
// HTML code to the left of the folder item
mainFolderLeft: '',
// HTML code to the right of the folder item
mainFolderRight: '',
// HTML code to the left of the regular item
mainItemLeft: '',
// HTML code to the right of the regular item
mainItemRight: '',
// sub menu display attributes
// HTML code to the left of the folder item
folderLeft: '',
// HTML code to the right of the folder item
folderRight: '',
// HTML code to the left of the regular item
itemLeft: '',
// HTML code to the right of the regular item
itemRight: '',
// cell spacing for main menu
mainSpacing: 0,
// cell spacing for sub menus
subSpacing: 0,
// optional settings
// If not set, use the default
// auto disappear time for submenus in milli-seconds
delay: 500,
// 1st layer sub menu starting index
zIndexStart: 1000,
// z-index incremental step for subsequent layers
zIndexInc: 5,
// sub menu header appears before the sub menu table
subMenuHeader: null,
// sub menu header appears after the sub menu table
subMenuFooter: null,
// submenu location adjustments
//
// offsetHMainAdjust for adjusting the first submenu
// of a 'hbr' menu.
// offsetVMainAdjust for adjusting the first submenu
// of a 'vbr' menu.
// offsetSubAdjust for subsequent level of submenus
//
offsetHMainAdjust: [0, 0],
offsetVMainAdjust: [0, 0],
offsetSubAdjust: [0, 0],
// act on click to open sub menu
// not yet implemented
// 0 : use default behavior
// 1 : hover open in all cases
// 2 : click on main, hover on sub
// 3 : click open in all cases (illegal as of 1.5)
clickOpen: 1,
// special effects on open/closing a sub menu
effect: null
};
// Globals
var _cmIDCount = 0;
var _cmIDName = 'cmSubMenuID'; // for creating submenu id
var _cmTimeOut = null; // how long the menu would stay
var _cmCurrentItem = null; // the current menu item being selected;
var _cmNoAction = new Object (); // indicate that the item cannot be hovered.
var _cmNoClick = new Object (); // similar to _cmNoAction but does not respond to mouseup/mousedown events
var _cmSplit = new Object (); // indicate that the item is a menu split
var _cmMenuList = new Array (); // a list of the current menus
var _cmItemList = new Array (); // a simple list of items
var _cmFrameList = new Array (); // a pool of reusable iframes
var _cmFrameListSize = 0; // keep track of the actual size
var _cmFrameIDCount = 0; // keep track of the frame id
var _cmFrameMasking = true; // use the frame masking
// disable iframe masking for IE7
/*@cc_on
@if (@_jscript_version >= 5.6)
if (_cmFrameMasking)
{
var v = navigator.appVersion;
var i = v.indexOf ("MSIE ");
if (i >= 0)
{
if (parseInt (navigator.appVersion.substring (i + 5)) >= 7)
_cmFrameMasking = false;
}
}
@end
@*/
var _cmClicked = false; // for onClick
// flag for turning on off hiding objects
//
// 0: automatic
// 1: hiding
// 2: no hiding
var _cmHideObjects = 0;
// Utility function to do a shallow copy a node property
function cmClone (nodeProperties)
{
var returnVal = new Object ();
for (v in nodeProperties)
returnVal[v] = nodeProperties[v];
return returnVal;
}
//
// store the new menu information into a structure to retrieve it later
//
function cmAllocMenu (id, menu, orient, nodeProperties, prefix)
{
var info = new Object ();
info.div = id;
info.menu = menu;
info.orient = orient;
info.nodeProperties = nodeProperties;
info.prefix = prefix;
var menuID = _cmMenuList.length;
_cmMenuList[menuID] = info;
return menuID;
}
//
// request a frame
//
function cmAllocFrame ()
{
if (_cmFrameListSize > 0)
return cmGetObject (_cmFrameList[--_cmFrameListSize]);
var frameObj = document.createElement ('iframe');
var id = _cmFrameIDCount++;
frameObj.id = 'cmFrame' + id;
frameObj.frameBorder = '0';
frameObj.style.display = 'none';
frameObj.src = 'javascript:false';
document.body.appendChild (frameObj);
frameObj.style.filter = 'alpha(opacity=0)';
frameObj.style.zIndex = 99;
frameObj.style.position = 'absolute';
frameObj.style.border = '0';
frameObj.scrolling = 'no';
return frameObj;
}
//
// make a frame resuable later
//
function cmFreeFrame (frameObj)
{
_cmFrameList[_cmFrameListSize++] = frameObj.id;
}
//////////////////////////////////////////////////////////////////////
//
// Drawing Functions and Utility Functions
//
//////////////////////////////////////////////////////////////////////
//
// produce a new unique id
//
function cmNewID ()
{
return _cmIDName + (++_cmIDCount);
}
//
// return the property string for the menu item
//
function cmActionItem (item, isMain, idSub, menuInfo, menuID)
{
_cmItemList[_cmItemList.length] = item;
var index = _cmItemList.length - 1;
idSub = (!idSub) ? 'null' : ('\'' + idSub + '\'');
var clickOpen = menuInfo.nodeProperties.clickOpen;
var onClick = (clickOpen == 3) || (clickOpen == 2 && isMain);
var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index;
var returnStr;
if (onClick)
returnStr = ' onmouseover="cmItemMouseOver(' + param + ',false)" onmousedown="cmItemMouseDownOpenSub (' + param + ')"';
else
returnStr = ' onmouseover="cmItemMouseOverOpenSub (' + param + ')" onmousedown="cmItemMouseDown (' + param + ')"';
return returnStr + ' onmouseout="cmItemMouseOut (' + param + ')" onmouseup="cmItemMouseUp (' + param + ')"';
}
//
// this one is used by _cmNoClick to only take care of onmouseover and onmouseout
// events which are associated with menu but not actions associated with menu clicking/closing
//
function cmNoClickItem (item, isMain, idSub, menuInfo, menuID)
{
// var index = _cmItemList.push (item) - 1;
_cmItemList[_cmItemList.length] = item;
var index = _cmItemList.length - 1;
idSub = (!idSub) ? 'null' : ('\'' + idSub + '\'');
var param = 'this,' + isMain + ',' + idSub + ',' + menuID + ',' + index;
return ' onmouseover="cmItemMouseOver (' + param + ')" onmouseout="cmItemMouseOut (' + param + ')"';
}
function cmNoActionItem (item)
{
return item[1];
}
function cmSplitItem (prefix, isMain, vertical)
{
var classStr = 'cm' + prefix;
if (isMain)
{
classStr += 'Main';
if (vertical)
classStr += 'HSplit';
else
classStr += 'VSplit';
}
else
classStr += 'HSplit';
return eval (classStr);
}
//
// draw the sub menu recursively
//
function cmDrawSubMenu (subMenu, prefix, id, nodeProperties, zIndexStart, menuInfo, menuID)
{
var str = '<div class="' + prefix + 'SubMenu" id="' + id + '" style="z-index: ' + zIndexStart + ';position: absolute; top: 0px; left: 0px;">';
if (nodeProperties.subMenuHeader)
str += nodeProperties.subMenuHeader;
str += '<table summary="sub menu" id="' + id + 'Table" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">';
var strSub = '';
var item;
var idSub;
var hasChild;
var i;
var classStr;
for (i = 5; i < subMenu.length; ++i)
{
item = subMenu[i];
if (!item)
continue;
if (item == _cmSplit)
item = cmSplitItem (prefix, 0, true);
item.parentItem = subMenu;
item.subMenuID = id;
hasChild = (item.length > 5);
idSub = hasChild ? cmNewID () : null;
str += '<tr class="' + prefix + 'MenuItem"';
if (item[0] != _cmNoClick)
str += cmActionItem (item, 0, idSub, menuInfo, menuID);
else
str += cmNoClickItem (item, 0, idSub, menuInfo, menuID);
str += '>'
if (item[0] == _cmNoAction || item[0] == _cmNoClick)
{
str += cmNoActionItem (item);
str += '</tr>';
continue;
}
classStr = prefix + 'Menu';
classStr += hasChild ? 'Folder' : 'Item';
str += '<td class="' + classStr + 'Left">';
if (item[0] != null)
str += item[0];
else
str += hasChild ? nodeProperties.folderLeft : nodeProperties.itemLeft;
str += '</td><td class="' + classStr + 'Text">' + item[1];
str += '</td><td class="' + classStr + 'Right">';
if (hasChild)
{
str += nodeProperties.folderRight;
strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, zIndexStart + nodeProperties.zIndexInc, menuInfo, menuID);
}
else
str += nodeProperties.itemRight;
str += '</td></tr>';
}
str += '</table>';
if (nodeProperties.subMenuFooter)
str += nodeProperties.subMenuFooter;
str += '</div>' + strSub;
return str;
}
//
// The function that builds the menu inside the specified element id.
//
// id id of the element
// orient orientation of the menu in [hv][ub][lr] format
// menu the menu object to be drawn
// nodeProperties properties for the theme
// prefix prefix of the theme
//
function cmDraw (id, menu, orient, nodeProperties, prefix)
{
var obj = cmGetObject (id);
if (!prefix)
prefix = nodeProperties.prefix;
if (!prefix)
prefix = '';
if (!nodeProperties)
nodeProperties = _cmNodeProperties;
if (!orient)
orient = 'hbr';
var menuID = cmAllocMenu (id, menu, orient, nodeProperties, prefix);
var menuInfo = _cmMenuList[menuID];
// setup potentially missing properties
if (!nodeProperties.delay)
nodeProperties.delay = _cmNodeProperties.delay;
if (!nodeProperties.clickOpen)
nodeProperties.clickOpen = _cmNodeProperties.clickOpen;
if (!nodeProperties.zIndexStart)
nodeProperties.zIndexStart = _cmNodeProperties.zIndexStart;
if (!nodeProperties.zIndexInc)
nodeProperties.zIndexInc = _cmNodeProperties.zIndexInc;
if (!nodeProperties.offsetHMainAdjust)
nodeProperties.offsetHMainAdjust = _cmNodeProperties.offsetHMainAdjust;
if (!nodeProperties.offsetVMainAdjust)
nodeProperties.offsetVMainAdjust = _cmNodeProperties.offsetVMainAdjust;
if (!nodeProperties.offsetSubAdjust)
nodeProperties.offsetSubAdjust = _cmNodeProperties.offsetSubAdjust;
// save user setting on frame masking
menuInfo.cmFrameMasking = _cmFrameMasking;
var str = '<table summary="main menu" class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '">';
var strSub = '';
var vertical;
// draw the main menu items
if (orient.charAt (0) == 'h')
{
str += '<tr>';
vertical = false;
}
else
{
vertical = true;
}
var i;
var item;
var idSub;
var hasChild;
var classStr;
for (i = 0; i < menu.length; ++i)
{
item = menu[i];
if (!item)
continue;
item.menu = menu;
item.subMenuID = id;
str += vertical ? '<tr' : '<td';
str += ' class="' + prefix + 'MainItem"';
hasChild = (item.length > 5);
idSub = hasChild ? cmNewID () : null;
str += cmActionItem (item, 1, idSub, menuInfo, menuID) + '>';
if (item == _cmSplit)
item = cmSplitItem (prefix, 1, vertical);
if (item[0] == _cmNoAction || item[0] == _cmNoClick)
{
str += cmNoActionItem (item);
str += vertical? '</tr>' : '</td>';
continue;
}
classStr = prefix + 'Main' + (hasChild ? 'Folder' : 'Item');
str += vertical ? '<td' : '<span';
str += ' class="' + classStr + 'Left">';
str += (item[0] == null) ? (hasChild ? nodeProperties.mainFolderLeft : nodeProperties.mainItemLeft)
: item[0];
str += vertical ? '</td>' : '</span>';
str += vertical ? '<td' : '<span';
str += ' class="' + classStr + 'Text">';
str += item[1];
str += vertical ? '</td>' : '</span>';
str += vertical ? '<td' : '<span';
str += ' class="' + classStr + 'Right">';
str += hasChild ? nodeProperties.mainFolderRight : nodeProperties.mainItemRight;
str += vertical ? '</td>' : '</span>';
str += vertical ? '</tr>' : '</td>';
if (hasChild)
{
strSub += cmDrawSubMenu (item, prefix, idSub, nodeProperties, nodeProperties.zIndexStart, menuInfo, menuID);
}
}
if (!vertical)
str += '</tr>';
str += '</table>' + strSub;
obj.innerHTML = str;
}
//
// The function builds the menu inside the specified element id.
//
// This function is similar to cmDraw except that menu is taken from HTML node
// rather a javascript tree. This feature allows links to be scanned by search
// bots.
//
// This function basically converts HTML node to a javascript tree, and then calls
// cmDraw to draw the actual menu, replacing the hidden menu tree.
//
// Format:
// <div id="menu">
// <ul style="visibility: hidden">
// <li><span>icon</span><a href="link" title="description">main menu text</a>
// <ul>
// <li><span>icon</span><a href="link" title="description">submenu item</a>
// </li>
// </ul>
// </li>
// </ul>
// </div>
//
function cmDrawFromText (id, orient, nodeProperties, prefix)
{
var domMenu = cmGetObject (id);
var menu = null;
for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)
{
if (!currentDomItem.tagName)
continue;
var tag = currentDomItem.tagName.toLowerCase ();
if (tag != 'ul' && tag != 'ol')
continue;
menu = cmDrawFromTextSubMenu (currentDomItem);
break;
}
if (menu)
cmDraw (id, menu, orient, nodeProperties, prefix);
}
//
// a recursive function that build menu tree structure
//
function cmDrawFromTextSubMenu (domMenu)
{
var items = new Array ();
for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling)
{
if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'li')
continue;
if (currentDomItem.firstChild == null)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -