📄 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 activate
Menu.keyboardAccelKey2 = 121; // the menubar
Menu.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 menus
Menu.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;
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -