dommenu.js
来自「IPcop软路由防火墙 FREE 开源源代码」· JavaScript 代码 · 共 1,168 行 · 第 1/3 页
JS
1,168 行
// {{{ docs <-- this is a VIM (text editor) text fold/** * DOM Menu 0.3.2 * * Summary: Allows developers to add dynamic drop down menus on webpages. The * menu can either be horizontal or vertical, and can open in either * direction. It has both edge detection and <select> tag detection * (for browsers that cannot hide these form elements). The styles * for the menu items are controlled almost entirely through CSS and * the menus are created and destroyed using the DOM. Menu configuration * is done using a custom Hash() class and is very portable from a PHP * type array structure. * * Maintainer: Dan Allen <dan@mojavelinux.com> * * License: LGPL - however, if you use this library, please post to my forum where you * use it so that I get a chance to see my baby in action. If you are doing * this for commercial work perhaps you could send me a few Starbucks Coffee * gift dollars to encourage future developement (NOT REQUIRED). E-mail me * for and address. * * Homepage: http://www.mojavelinux.com/forum/viewtopic.php * * Freshmeat Project: http://freshmeat.net/projects/dommenu/?topic_id=92 * * Updated: 2003/01/04 * * Supported Browsers: Mozilla (Gecko), IE 5+, Konqueror, (not finished Opera 7), Netscape 4 * * Usage: * * Menu Options: Each option is followed by the value for that option. The options avaiable are: * 'contents' * 'rolloverContents', * 'uri' (may be javascript) * 'statusText' * 'target' * [0-9] an index to create a submenu item * * API: * * menuElementObject { * ** properties ** * data * contents * uri * target * statusText * parentElement * subMenu * childElements * level * index (index within this level) * id * className * style * cellSpacing (Konq only) * * ** events ** * mouseover/click -> domMenu_openEvent * mouseout -> domMenu_closeEvent * click -> domMenu_resolveLink * } * * If there is a non-negative click open delay, then any uri of the element will be ignored * * The alternate contents for a hover element are treated by creating to <span> wrapper elements * and then alternating the display of them. This avoids the need for innerHTML, which can * do nasty things to the browsers. If <span> turns out to be a bad choice for tags, then a * non-HTML element can be used instead. ***/// }}}// {{{ settings (editable)var domMenu_data = new domMenu_Hash();var domMenu_settings = new domMenu_Hash();domMenu_settings.setItem('global', new domMenu_Hash( 'menuBarClass', 'domMenu_menuBar', 'menuElementClass', 'domMenu_menuElement', 'menuElementHoverClass', 'domMenu_menuElementHover', 'menuElementActiveClass', 'domMenu_menuElementHover', 'subMenuBarClass', 'domMenu_subMenuBar', 'subMenuElementClass', 'domMenu_subMenuElement', 'subMenuElementHoverClass', 'domMenu_subMenuElementHover', 'subMenuElementActiveClass', 'domMenu_subMenuElementHover', 'subMenuElementHeadingClass', 'domMenu_subMenuElementHeading', 'menuBarWidth', '100%', 'subMenuMinWidth', 'inherit', 'distributeSpace', true, 'axis', 'horizontal', 'verticalExpand', 'south', 'horizontalExpand', 'east', 'subMenuWidthCorrection', 0, 'verticalSubMenuOffsetY', 0, 'verticalSubMenuOffsetX', 0, 'horizontalSubMenuOffsetX', 0, 'horizontalSubMenuOffsetY', 0, 'screenPadding', 0, 'openMouseoverMenuDelay', 300, 'openMousedownMenuDelay', -1, 'closeMouseoutMenuDelay', 800, 'closeClickMenuDelay', -1, 'openMouseoverSubMenuDelay', 300, 'openClickSubMenuDelay', -1, 'closeMouseoutSubMenuDelay', 300, 'closeClickSubMenuDelay', -1, 'baseZIndex', 100));// }}}// {{{ global variables/** * Browser variables * @var domMenu_is{Browser} */var domMenu_userAgent = navigator.userAgent.toLowerCase();var domMenu_isOpera = domMenu_userAgent.indexOf('opera 7') != -1 ? 1 : 0;var domMenu_isKonq = domMenu_userAgent.indexOf('konq') != -1 ? 1 : 0;var domMenu_isIE = !domMenu_isKonq && !domMenu_isOpera && document.all ? 1 : 0;var domMenu_isIE50 = domMenu_isIE && domMenu_userAgent.indexOf('msie 5.0') != -1;var domMenu_isIE55 = domMenu_isIE && domMenu_userAgent.indexOf('msie 5.5') != -1;var domMenu_isIE5 = domMenu_isIE50 || domMenu_isIE55;var domMenu_isGecko = !domMenu_isKonq && domMenu_userAgent.indexOf('gecko') != -1 ? 1 : 0;/** * Passport to use the menu system, checked before performing menu manipulation * @var domMenu_useLibrary */var domMenu_useLibrary = domMenu_isIE || domMenu_isGecko || domMenu_isKonq || domMenu_isOpera ? 1 : 0;/** * The data for the menu is stored here, loaded from an external file * @hash domMenu_data */var domMenu_data;var domMenu_selectElements;var domMenu_scrollbarWidth = 14;var domMenu_eventTo = domMenu_isIE ? 'toElement' : 'relatedTarget';var domMenu_eventFrom = domMenu_isIE ? 'fromElement' : 'relatedTarget';var domMenu_activeElement = new domMenu_Hash();/** * Array of hashes listing the timouts currently running for opening/closing menus * @array domMenu_timeouts */var domMenu_timeouts = new Array();domMenu_timeouts['open'] = new domMenu_Hash();domMenu_timeouts['close'] = new domMenu_Hash();var domMenu_timeoutStates = new Array();domMenu_timeoutStates['open'] = new domMenu_Hash();domMenu_timeoutStates['close'] = new domMenu_Hash();/** * Style to use for a link pointer, which is different between Gecko and IE * @var domMenu_pointerStyle */var domMenu_pointerStyle = domMenu_isIE ? 'hand' : 'pointer';// }}}// {{{ domMenu_Hash()function domMenu_Hash() { var argIndex = 0; this.length = 0; this.numericLength = 0; this.items = new Array(); while (arguments.length > argIndex) { this.items[arguments[argIndex]] = arguments[argIndex + 1]; if (arguments[argIndex] == parseInt(arguments[argIndex])) { this.numericLength++; } this.length++; argIndex += 2; } this.removeItem = function(in_key) { var tmp_value; if (typeof(this.items[in_key]) != 'undefined') { this.length--; if (in_key == parseInt(in_key)) { this.numericLength--; } tmp_value = this.items[in_key]; delete this.items[in_key]; } return tmp_value; } this.getItem = function(in_key) { return this.items[in_key]; } this.setItem = function(in_key, in_value) { if (typeof(this.items[in_key]) == 'undefined') { this.length++; if (in_key == parseInt(in_key)) { this.numericLength++; } } this.items[in_key] = in_value; } this.hasItem = function(in_key) { return typeof(this.items[in_key]) != 'undefined'; } this.merge = function(in_hash) { for (var tmp_key in in_hash.items) { if (typeof(this.items[tmp_key]) == 'undefined') { this.length++; if (tmp_key == parseInt(tmp_key)) { this.numericLength++; } } this.items[tmp_key] = in_hash.items[tmp_key]; } } this.compare = function(in_hash) { if (this.length != in_hash.length) { return false; } for (var tmp_key in this.items) { if (this.items[tmp_key] != in_hash.items[tmp_key]) { return false; } } return true; }}// }}}// {{{ domMenu_activate()function domMenu_activate(in_containerId){ var container; var data; // make sure we can use the menu system and this is a valid menu if (!domMenu_useLibrary || !(container = document.getElementById(in_containerId)) || !(data = domMenu_data.items[in_containerId])) { return; } // start with the global settings and merge in the local changes if (!domMenu_settings.hasItem(in_containerId)) { domMenu_settings.setItem(in_containerId, new domMenu_Hash()); } var settings = domMenu_settings.items[in_containerId]; for (var i in domMenu_settings.items['global'].items) { if (!settings.hasItem(i)) { settings.setItem(i, domMenu_settings.items['global'].items[i]); } } // populate the zero level element container.data = new domMenu_Hash( 'parentElement', false, 'numChildren', data.numericLength, 'childElements', new domMenu_Hash(), 'level', 0, 'index', 1 ); // if we choose to distribute either height or width, determine ratio of each cell var distributeRatio = Math.round(100/container.data.items['numChildren']) + '%'; // the first menu is the rootMenu, which is a child of the zero level element var rootMenu = document.createElement('div'); rootMenu.id = in_containerId + '[0]'; rootMenu.className = settings.items['menuBarClass']; container.data.setItem('subMenu', rootMenu); var rootMenuTable = rootMenu.appendChild(document.createElement('table')); if (domMenu_isKonq) { rootMenuTable.cellSpacing = 0; } rootMenuTable.style.border = 0; rootMenuTable.style.borderCollapse = 'collapse'; rootMenuTable.style.width = settings.items['menuBarWidth']; var rootMenuTableBody = rootMenuTable.appendChild(document.createElement('tbody')); var numSiblings = container.data.items['numChildren']; for (var index = 1; index <= numSiblings; index++) { // create a row the first time if horizontal or each time if vertical if (index == 1 || settings.items['axis'] == 'vertical') { var rootMenuTableRow = rootMenuTableBody.appendChild(document.createElement('tr')); } // create an instance of the root level menu element var rootMenuTableCell = rootMenuTableRow.appendChild(document.createElement('td')); rootMenuTableCell.style.padding = 0; rootMenuTableCell.id = in_containerId + '[' + index + ']'; // add element to list of parent children container.data.items['childElements'].setItem(rootMenuTableCell.id, rootMenuTableCell); // assign the settings to the root level element // {!} this is a problem if two menus are using the same data {!} rootMenuTableCell.data = data.items[index]; rootMenuTableCell.data.merge(new domMenu_Hash( 'basename', in_containerId, 'parentElement', container, 'numChildren', rootMenuTableCell.data.numericLength, 'childElements', new domMenu_Hash(), 'offsets', new domMenu_Hash(), 'level', container.data.items['level'] + 1, 'index', index )); // assign the styles rootMenuTableCell.style.cursor = 'default'; if (settings.items['axis'] == 'horizontal') { if (settings.items['distributeSpace']) { rootMenuTableCell.style.width = distributeRatio; } } var rootElement = rootMenuTableCell.appendChild(document.createElement('div')); rootElement.className = settings.items['menuElementClass']; // fill in the menu element contents rootElement.innerHTML = '<span>' + rootMenuTableCell.data.items['contents'] + '</span>' + (rootMenuTableCell.data.hasItem('contentsHover') ? '<span style="display: none;">' + rootMenuTableCell.data.items['contentsHover'] + '</span>' : ''); // attach the events rootMenuTableCell.onmouseover = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMouseoverMenuDelay']); }; rootMenuTableCell.onmouseout = function(in_event) { domMenu_closeEvent(this, in_event); }; if (settings.items['openMousedownMenuDelay'] >= 0 && rootMenuTableCell.data.items['numChildren']) { rootMenuTableCell.onmousedown = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMousedownMenuDelay']); }; // cancel mouseup so that it doesn't propogate to global mouseup event rootMenuTableCell.onmouseup = function(in_event) { var eventObj = domMenu_isIE ? event : in_event; eventObj.cancelBubble = true; }; if (domMenu_isIE) { rootMenuTableCell.ondblclick = function(in_event) { domMenu_openEvent(this, in_event, settings.items['openMousedownMenuDelay']); }; } } else if (rootMenuTableCell.data.items['uri']) { rootMenuTableCell.style.cursor = domMenu_pointerStyle; rootMenuTableCell.onclick = function(in_event) { domMenu_resolveLink(this, in_event); }; } // prevent highlighting of text if (domMenu_isIE) { rootMenuTableCell.onselectstart = function() { return false; }; } rootMenuTableCell.oncontextmenu = function() { return false; }; } // add the menu rootMenu to the zero level element rootMenu = container.appendChild(rootMenu); // even though most cases the top level menu does not go away, it could // if this menu system is used by another process domMenu_detectCollisions(rootMenu);}// }}}// {{{ domMenu_activateSubMenu()function domMenu_activateSubMenu(in_parentElement){ // see if submenu already exists if (in_parentElement.data.hasItem('subMenu')) { domMenu_toggleSubMenu(in_parentElement, 'visible'); return; } var settings = domMenu_settings.items[in_parentElement.data.items['basename']];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?