📄 menu4.js
字号:
/*----------------------------------------------------------------------------\| DHTML Menu 4.28 ||-----------------------------------------------------------------------------|| Created by Erik Arvidsson || (http://webfx.eae.net/contact.html#erik) || For WebFX (http://webfx.eae.net/) ||-----------------------------------------------------------------------------|| A menu system for Internet Explorer 5.5+ Win32 that allows menus to extend || outside the browser window limits. ||-----------------------------------------------------------------------------|| Copyright (c) 1999 - 2003 Erik Arvidsson ||-----------------------------------------------------------------------------|| This software is provided "as is", without warranty of any kind, express or || implied, including but not limited to the warranties of merchantability, || fitness for a particular purpose and noninfringement. In no event shall the || authors or copyright holders be liable for any claim, damages or other || liability, whether in an action of contract, tort or otherwise, arising || from, out of or in connection with the software or the use or other || dealings in the software. || - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - || This software is available under the three different licenses mentioned || below. To use this software you must chose, and qualify, for one of those. || - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - || The WebFX Non-Commercial License http://webfx.eae.net/license.html || Permits anyone the right to use the software in a non-commercial context || free of charge. || - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - || The WebFX Commercial license http://webfx.eae.net/commercial.html || Permits the license holder the right to use the software in a commercial || context. Such license must be specifically obtained, however it's valid for || any number of implementations of the licensed software. || - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - || GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt || Permits anyone the right to use and modify the software without limitations || as long as proper credits are given and the original and modified source || code are included. Requires that the final product, software derivate from || the original source or any software utilizing a GPL component, such as || this, is also licensed under the GPL license. ||-----------------------------------------------------------------------------|| 2002-05-28 | First version || 2002-06-07 | Updated default cssFile value to "skins/winclassic.css" || | instead of "winclassic.css" || 2002-06-10 | (4.1) Lots of changes. Rewrote measuring and positioning || | routines to prevent screen flicker. As well as general code || | optimization. || 2002-07-03 | getInsetRight and getInsetBottom broke in the last update. || | Radio and Check box did not check disabled state correctly. || 2002-07-25 | Created a work around for a weird bug that did not show first || | menu. Disabled browser keyboard shortcuts when menus are open. || | Added workaround for buggy dual monitor drivers. || 2002-09-05 | Fixed cases where the caching of the CSS failed and caused the || | cached menu size to be incorrect. || 2002-09-05 | Insets were ignored for vertical menus. || 2002-09-06 | Some properties have been moved to the prototype to make || | customizing easier. || 2002-09-24 | Minor changes to prevent size errors. || 2002-10-22 | Added second argument to Menu add. || | Added support for Menu cssText. || 2002-10-29 | (4.2) Lots of work to work around IE memory bugs. || 2002-11-03 | Typo in MenuBar goToNextMenuItem || 2002-11-23 | The height and width were not correctly limited in show. || 2002-12-04 | Changed to use onunload instead of onbeforeunload. || | Onbeforeunload was causing troubles with certain links. || 2003-03-07 | Fixed bug in MenuButton toHtml and added MenuBar invalidate || | also created a clone extension (menu4.clone.js) || 2003-04-01 | added document arguments to MenuBar create and write. || | Better mnemonic handling when HTML is used || | onclose, onshow and onbeforeshow || 2003-09-12 | Updated mnemonic code and fixed an itemIndex bug when adding || | items. || 2003-09-23 | The scrollbutton.js still used onbeforeunload || 2003-10-15 | Add support for keyboardAccelKey2 (defaults to F10). Also || | fixed so that Esc on last menu correctly goes to the menu bar. || 2003-11-24 | Changed the MenuButton constructor to not fail if sub menu is || | left out. This allows you to set the sub menu later. A sub || | menu is still needed! ||-----------------------------------------------------------------------------|| Dependencies: poslib.js Used to find positions of elements || scrollbutton.js Used for the buttnos that allows the menu || to be scrollable ||-----------------------------------------------------------------------------|| Created 2002-05-28 | All changes are in the log above. | Updated 2003-11-24 |\----------------------------------------------------------------------------*/////////////////////////////////////////////////////////////////////////////////////// menuCache//var menuCache = { _count: 0, _idPrefix: "-menu-cache-", getId: function () { return this._idPrefix + this._count++; }, remove: function ( o ) { delete this[ o.id ]; }};////////////////////////////////////////////////////////////////////////////////////// Menu//function Menu() { this.items = []; this.parentMenu = null; this.parentMenuItem = null; this.popup = null; this.shownSubMenu = null; this._aboutToShowSubMenu = false; this.selectedIndex = -1; this._drawn = false; this._scrollingMode = false; this._showTimer = null; this._closeTimer = null; this._onCloseInterval = null; this._closed = true; this._closedAt = 0; this._cachedSizes = {}; this._measureInvalid = true; this.id = menuCache.getId(); menuCache[ this.id ] = this;}Menu.prototype.cssFile = "skins/winclassic.css";Menu.prototype.cssText = null;Menu.prototype.mouseHoverDisabled = true;Menu.prototype.showTimeout = 250;Menu.prototype.closeTimeout = 250;Menu.keyboardAccelKey = 27; // the keyCode for the key tp activateMenu.keyboardAccelKey2 = 121; // the menubarMenu.keyboardAccelProperty = "ctrlKey"; // when this property is true default // actions will be canceled on a menu// Use -1 to disable keyboard invoke of the menubar// Use "" to allow all normal keyboard commands inside the menusMenu.prototype.add = function ( mi, beforeMi ) { if ( beforeMi != null ) { var items = this.items; var l = items.length; var i = 0; for ( ; i < l; i++ ) { if ( items[i] == beforeMi ) break; } this.items = items.slice( 0, i ).concat( mi ).concat( items.slice( i, l ) ); // update itemIndex for (var j = i; j < l + 1; j++) this.items[j].itemIndex = j; } else { this.items.push( mi ); mi.itemIndex = this.items.length - 1; } mi.parentMenu = this; if ( mi.subMenu ) { mi.subMenu.parentMenu = this; mi.subMenu.parentMenuItem = mi; } return mi;};Menu.prototype.remove = function ( mi ) { var res = []; var items = this.items; var l = items.length; for (var i = 0; i < l; i++) { if ( items[i] != mi ) { res.push( items[i] ); items[i].itemIndex = res.length - 1; } } this.items = res; mi.parentMenu = null; return mi;};Menu.prototype.toHtml = function () { var items = this.items; var l = items.length var itemsHtml = new Array( l ); for (var i = 0; i < l; i++) itemsHtml[i] = items[i].toHtml(); return "<html><head>" + (this.cssText == null ? "<link type=\"text/css\" rel=\"StyleSheet\" href=\"" + this.cssFile + "\" />" : "<style type=\"text/css\">" + this.cssText + "</style>") + "</head><body class=\"menu-body\">" + "<div class=\"outer-border\"><div class=\"inner-border\">" + "<table id=\"scroll-up-item\" cellspacing=\"0\" style=\"display: none\">" + "<tr class=\"disabled\"><td>" + "<span class=\"disabled-container\"><span class=\"disabled-container\">" + "5" + "</span></span>" + "</td></tr></table>" + "<div id=\"scroll-container\">" + "<table cellspacing=\"0\">" + itemsHtml.join( "" ) + "</table>" + "</div>" + "<table id=\"scroll-down-item\" cellspacing=\"0\" style=\"display: none\">" + "<tr><td>" + "<span class=\"disabled-container\"><span class=\"disabled-container\">" + "6" + "</span></span>" + "</td></tr></table>" + "</div></div>" + "</body></html>";};Menu.prototype.createPopup = function () { var w; var pm = this.parentMenu; if ( pm == null ) w = window; else w = pm.getDocument().parentWindow; this.popup = w.createPopup();};Menu.prototype.getMeasureDocument = function () { if ( this.isShown() && this._drawn ) return this.getDocument(); var mf = Menu._measureFrame; if ( mf == null ) { // should be top document mf = Menu._measureFrame = document.createElement("IFRAME"); var mfs = mf.style; mfs.position = "absolute"; mfs.visibility = "hidden"; mfs.left = "-100px"; mfs.top = "-100px"; mfs.width = "10px"; mfs.height = "10px"; mf.frameBorder = 0; document.body.appendChild( mf ); } var d = mf.contentWindow.document if ( Menu._measureMenu == this && !this._measureInvalid ) return d; d.open( "text/html", "replace" ); d.write( this.toHtml() ); d.close(); Menu._measureMenu = this; this._measureInvalid = false; return d;};Menu.prototype.getDocument = function () { if ( this.popup ) return this.popup.document; else return null;};Menu.prototype.getPopup = function () { if ( this.popup == null ) this.createPopup(); return this.popup;};Menu.prototype.invalidate = function () { if ( this._drawn ) { // do some memory cleanup if ( this._scrollUpButton ) this._scrollUpButton.destroy(); if ( this._scrollDownButton ) this._scrollDownButton.destroy(); var items = this.items; var l = items.length; var mi; for ( var i = 0; i < l; i++ ) { mi = items[i]; mi._htmlElement_menuItem = null; mi._htmlElement = null; } this.detachEvents(); } this._drawn = false; this.resetSizeCache(); this._measureInvalid = true;};Menu.prototype.redrawMenu = function () { this.invalidate(); this.drawMenu();};Menu.prototype.drawMenu = function () { if ( this._drawn ) return; this.getPopup(); var d = this.getDocument(); d.open( "text/html", "replace" ); d.write( this.toHtml() ); d.close(); this._drawn = true; // set up scroll buttons var up = d.getElementById( "scroll-up-item" ); var down = d.getElementById( "scroll-down-item" ); var scrollContainer = d.getElementById( "scroll-container" ); new ScrollButton( up, scrollContainer, 8 ); new ScrollButton( down, scrollContainer, 2 ); // bind menu items to the table rows var rows = scrollContainer.firstChild.tBodies[0].rows; var items = this.items; var l = rows.length; var mi; for ( var i = 0; i < l; i++ ) { mi = items[i]; rows[i]._menuItem = mi; mi._htmlElement = rows[i]; } // hook up mouse this.hookupMenu( d );};Menu.prototype.show = function ( left, top, w, h ) { var pm = this.parentMenu; if ( pm ) pm.closeAllSubs( this ); var wasShown = this.isShown(); if ( typeof this.onbeforeshow == "function" && !wasShown ) this.onbeforeshow(); this.drawMenu(); if ( left == null ) left = 0; if ( top == null ) top = 0; w = w || Math.min( window.screen.width, this.getPreferredWidth() ); h = h || Math.min( window.screen.height, this.getPreferredHeight() ); this.popup.show( left, top, w, h ); // work around a bug that sometimes occured with large pages when // opening the first menu if ( this.getPreferredWidth() == 0 ) { this.invalidate(); this.show( left, top, w, h ); return; } this.fixScrollButtons(); this.fixScrollEnabledState(); // clear selected item if ( this.selectedIndex != -1 ) { if ( this.items[ this.selectedIndex ] ) this.items[ this.selectedIndex ].setSelected( false ); } if ( pm ) { pm.shownSubMenu = this; pm._aboutToShowSubMenu = false; } window.clearTimeout( this._showTimer ); window.clearTimeout( this._closeTimer ); this._closed = false; this._startClosePoll(); if ( typeof this.onshow == "function" && !wasShown && this.isShown() ) this.onshow();};Menu.prototype.isShown = function () { this._checkCloseState(); return this.popup != null && this.popup.isOpen;};Menu.prototype.fixSize = function () { var w = Math.min( window.screen.width, this.getPreferredWidth() ); var h = Math.min( window.screen.height, this.getPreferredHeight() ); var l = Math.max( 0, this.getLeft() ); var t = Math.max( 0, this.getTop() ); this.popup.show( l, t, w, h );};Menu.prototype.getWidth = function () { var d = this.getDocument(); if ( d != null ) return d.body.offsetWidth; else return 0;};Menu.prototype.getHeight = function () { var d = this.getDocument(); if ( d != null ) return d.body.offsetHeight; else return 0;};Menu.prototype.getPreferredWidth = function () { this.updateSizeCache(); return this._cachedSizes.preferredWidth;};Menu.prototype.getPreferredHeight = function () { this.updateSizeCache(); return this._cachedSizes.preferredHeight;};Menu.prototype.getLeft = function () { var d = this.getDocument(); if ( d != null ) return d.parentWindow.screenLeft; else return 0;};Menu.prototype.getTop = function () { var d = this.getDocument(); if ( d != null ) return d.parentWindow.screenTop; else return 0;};// Depreciated. Use show insteadMenu.prototype.setLeft = function ( l ) { throw new Error("Depreciated. Use show instead"); //var t = this.getTop(); //this.setLocation( l, t );};// Depreciated. Use show insteadMenu.prototype.setTop = function ( t ) { throw new Error("Depreciated. Use show instead"); //var l = this.getLeft(); //this.setLocation( l, t );};// Depreciated. Use show insteadMenu.prototype.setLocation = function ( l, t ) { throw new Error("Depreciated. Use show instead"); //var w = this.getWidth(); //var h = this.getHeight(); //this.popup.show( l, t, w, h );};// Depreciated. Use show insteadMenu.prototype.setRect = function ( l, t, w, h ) { throw new Error("Depreciated. Use show instead"); //this.popup.show( l, t, w, h );};Menu.prototype.getInsetLeft = function () { this.updateSizeCache(); return this._cachedSizes.insetLeft;};Menu.prototype.getInsetRight = function () { this.updateSizeCache(); return this._cachedSizes.insetRight;};Menu.prototype.getInsetTop = function () { this.updateSizeCache(); return this._cachedSizes.insetTop;};Menu.prototype.getInsetBottom = function () { this.updateSizeCache(); return this._cachedSizes.insetBottom;};Menu.prototype.areSizesCached = function () { var cs = this._cachedSizes; return this._drawn && "preferredWidth" in cs && "preferredHeight" in cs && "insetLeft" in cs && "insetRight" in cs && "insetTop" in cs && "insetBottom" in cs;};// depreciatedMenu.prototype.cacheSizes = function ( bForce ) { return updateSizeCache( bForce );};Menu.prototype.resetSizeCache = function () { this._cachedSizes = {};};Menu.prototype.updateSizeCache = function ( bForce ) { if ( this.areSizesCached() && !bForce ) return; var d = this.getMeasureDocument(); var body = d.body; var cs = this._cachedSizes = {}; // reset var scrollContainer = d.getElementById( "scroll-container" ); // preferred width cs.preferredWidth = d.body.scrollWidth; // preferred height scrollContainer.style.overflow = "visible"; cs.preferredHeight = body.firstChild.offsetHeight; //body.scrollHeight; scrollContainer.style.overflow = "hidden"; // inset left cs.insetLeft = posLib.getLeft( scrollContainer );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -