效果图:
用法:
Fixed in FF
// JScript 文件
// by XiaoNiu evlion@qq.com
// 2009.4.22 修正在FF下不能使用的BUG
Evlon={};
Evlon.createDelegate = function(instance, method)
{
return function()
{
method.apply(instance, arguments);
}
}
Evlon.getChildren = function(elmt, filter/* var f = {tagName='li'}*/) {
var elmts = [];
var e = elmt.firstChild;
while (e != null) {
if (e.nodeType != 3) {
var valid = true;
if (filter != null) {
for (var key in filter) {
if (e[key] != filter[key]) {
valid = false;
break;
}
}
}
if (valid) {
elmts.push(e);
}
}
e = e.nextSibling;
}
return elmts;
}
Evlon.MenuItem = function(menuWrap, elmt, menuFocusClassName) {
this.menuWrap = menuWrap;
this.elmt = elmt;
this.menuFocusClassName = menuFocusClassName;
this.onclickHandle = this.elmt.onclick;
this.elmt.onclick = null;
this.hide = function() {
var re = new RegExp("\\s+" + menuFocusClassName, "ig");
var className = ' ' + this.elmt.className.toString();
this.elmt.className = className.replace(re, '');
}
this.show = function(doclick) {
this.elmt.className += ' ' + menuFocusClassName;
if (doclick && this.onclickHandle != null) {
this.onclickHandle();
}
}
this.menu_onclick = function() {
this.menuWrap.switchmenu(this,true);
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
}
this.hide();
if (this.elmt.addEventListener)
this.elmt.addEventListener('click', Evlon.createDelegate(this, this.menu_onclick), false);
else if (this.elmt.attachEvent)
this.elmt.attachEvent('onclick', Evlon.createDelegate(this, this.menu_onclick));
}
Evlon.MenuItemWrap = function(menuWnd, elmt, menuFocusClassName, elmtContent, menuItemFocusClassName) {
this.menuWnd = menuWnd;
this.elmt = elmt;
this.menuFocusClassName = menuFocusClassName;
this.menuItemFocusClassName = menuItemFocusClassName;
this.content = elmtContent;
this.subMenuItems = [];
this.menuWnd.currentMenuItem = null;
this.switchmenu = function(newmenu, doclick) {
if (this.menuWnd.currentMenuItem != newmenu) {
if (this.menuWnd.currentMenuItem != null)
this.menuWnd.currentMenuItem.hide();
this.menuWnd.currentMenuItem = newmenu;
this.menuWnd.currentMenuItem.show(doclick);
}
}
this.isHide = function()
{
return this.content.style.display == 'none';
}
this.hide = function() {
var re = new RegExp("\\s+" + menuFocusClassName, "ig");
var className = ' ' + this.elmt.className.toString();
this.elmt.className = className.replace(re, '');
this.content.style.display = 'none';
if(this.menuWnd.currentMenuItem != null)
this.menuWnd.currentMenuItem.hide();
}
this.show = function(defaultItemIndex) {
if(this.isHide())
{
this.elmt.className += ' ' + menuFocusClassName;
this.content.style.display = '';
if(defaultItemIndex == null)
{
// 加载配置
var itemIndex = this.getItemIndex();
if(typeof(this.menuWnd.profile[itemIndex]) == 'number')
{
defaultItemIndex = this.menuWnd.profile[itemIndex];
}
}
if(defaultItemIndex!= null && defaultItemIndex >= 0 && defaultItemIndex < this.subMenuItems.length)
{
this.switchmenu(this.subMenuItems[defaultItemIndex],true);
}
else if(this.menuWnd.currentMenuItem != null)
{
this.menuWnd.currentMenuItem.show(false);
}
}
}
this.toggle = function()
{
if(this.isHide())
{
this.show();
}
else
{
this.hide();
}
}
this.menu_onclick = function() {
this.menuWnd.switchmenu(this,null,false);
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
}
this.hide();
if (this.elmt.addEventListener)
this.elmt.addEventListener('click', Evlon.createDelegate(this, this.menu_onclick), false);
else if (this.elmt.attachEvent)
this.elmt.attachEvent('onclick', Evlon.createDelegate(this, this.menu_onclick));
if (this.content.addEventListener)
this.content.addEventListener('click', function(){
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
},false
);
else if (this.content.attachEvent)
this.content.attachEvent('onclick', function(){
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
}
);
var subMenus = Evlon.getChildren(this.content, { tagName: "LI" })
for (var i = 0; i < subMenus.length; ++i) {
var subMenu = subMenus[i];
this.subMenuItems.push(new Evlon.MenuItem(this, subMenu, menuItemFocusClassName));
}
this.getItemIndex = function()
{
for(var i = 0; i < this.menuWnd.menus.length; ++i)
{
if(this.menuWnd.menus[i] == this)
return i;
}
return -1;
}
}
Evlon.QQMenu = function(idMenu, menuFocusClassName, menuItemFocusClassName, defaultMenuIndex, defaultItemIndex, profile /*[{main:0,item:0},{main:1,item:0}]*/) {
this._menu = (typeof (idMenu) == 'string') ? document.getElementById(idMenu) : idMenu;
this.menus = [];
this.currentMenu = null;
this.currentMenuItem = null;
this.profile = {}; /* {menuIndex: itemIndex}*/
this.switchmenu = function(newmenu, defaultItemIndex) {
if (this.currentMenu != newmenu) {
if (this.currentMenu != null)
this.currentMenu.hide();
this.currentMenu = newmenu;
this.currentMenu.show(defaultItemIndex);
}
else {
this.currentMenu.toggle();
}
}
var childrens = Evlon.getChildren(this._menu, { tagName: 'LI' }); //.childNodes;
if (childrens.length > 0) {
for (var i = 0; i < childrens.length; ++i) {
var li = childrens[i];
var contents = Evlon.getChildren(li, { tagName: 'UL' });
if (contents.length != 1)
throw '必须只有一个子UL标签';
this.menus.push(new Evlon.MenuItemWrap(this, li, menuFocusClassName, contents[0], menuItemFocusClassName));
}
//变换配置
if(typeof(profile) == 'object')
{
for(var i = 0; i < profile.length; ++i)
{
this.profile[profile[i].main] = profile[i].item;
}
}
this.switchmenu(this.menus[defaultMenuIndex],defaultItemIndex);
}
}
// JScript 文件
// by XiaoNiu evlion@qq.com
// 2009.4.22 修正在FF下不能使用的BUG
Evlon={};
Evlon.createDelegate = function(instance, method)
{
return function()
{
method.apply(instance, arguments);
}
}
Evlon.getChildren = function(elmt, filter/* var f = {tagName='li'}*/) {
var elmts = [];
var e = elmt.firstChild;
while (e != null) {
if (e.nodeType != 3) {
var valid = true;
if (filter != null) {
for (var key in filter) {
if (e[key] != filter[key]) {
valid = false;
break;
}
}
}
if (valid) {
elmts.push(e);
}
}
e = e.nextSibling;
}
return elmts;
}
Evlon.MenuItem = function(menuWrap, elmt, menuFocusClassName) {
this.menuWrap = menuWrap;
this.elmt = elmt;
this.menuFocusClassName = menuFocusClassName;
this.onclickHandle = this.elmt.onclick;
this.elmt.onclick = null;
this.hide = function() {
var re = new RegExp("\\s+" + menuFocusClassName, "ig");
var className = ' ' + this.elmt.className.toString();
this.elmt.className = className.replace(re, '');
}
this.show = function(doclick) {
this.elmt.className += ' ' + menuFocusClassName;
if (doclick && this.onclickHandle != null) {
this.onclickHandle();
}
}
this.menu_onclick = function() {
this.menuWrap.switchmenu(this,true);
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
}
this.hide();
if (this.elmt.addEventListener)
this.elmt.addEventListener('click', Evlon.createDelegate(this, this.menu_onclick), false);
else if (this.elmt.attachEvent)
this.elmt.attachEvent('onclick', Evlon.createDelegate(this, this.menu_onclick));
}
Evlon.MenuItemWrap = function(menuWnd, elmt, menuFocusClassName, elmtContent, menuItemFocusClassName) {
this.menuWnd = menuWnd;
this.elmt = elmt;
this.menuFocusClassName = menuFocusClassName;
this.menuItemFocusClassName = menuItemFocusClassName;
this.content = elmtContent;
this.subMenuItems = [];
this.menuWnd.currentMenuItem = null;
this.switchmenu = function(newmenu, doclick) {
if (this.menuWnd.currentMenuItem != newmenu) {
if (this.menuWnd.currentMenuItem != null)
this.menuWnd.currentMenuItem.hide();
this.menuWnd.currentMenuItem = newmenu;
this.menuWnd.currentMenuItem.show(doclick);
}
}
this.isHide = function()
{
return this.content.style.display == 'none';
}
this.hide = function() {
var re = new RegExp("\\s+" + menuFocusClassName, "ig");
var className = ' ' + this.elmt.className.toString();
this.elmt.className = className.replace(re, '');
this.content.style.display = 'none';
if(this.menuWnd.currentMenuItem != null)
this.menuWnd.currentMenuItem.hide();
}
this.show = function(defaultItemIndex) {
if(this.isHide())
{
this.elmt.className += ' ' + menuFocusClassName;
this.content.style.display = '';
if(defaultItemIndex == null)
{
// 加载配置
var itemIndex = this.getItemIndex();
if(typeof(this.menuWnd.profile[itemIndex]) == 'number')
{
defaultItemIndex = this.menuWnd.profile[itemIndex];
}
}
if(defaultItemIndex!= null && defaultItemIndex >= 0 && defaultItemIndex < this.subMenuItems.length)
{
this.switchmenu(this.subMenuItems[defaultItemIndex],true);
}
else if(this.menuWnd.currentMenuItem != null)
{
this.menuWnd.currentMenuItem.show(false);
}
}
}
this.toggle = function()
{
if(this.isHide())
{
this.show();
}
else
{
this.hide();
}
}
this.menu_onclick = function() {
this.menuWnd.switchmenu(this,null,false);
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
}
this.hide();
if (this.elmt.addEventListener)
this.elmt.addEventListener('click', Evlon.createDelegate(this, this.menu_onclick), false);
else if (this.elmt.attachEvent)
this.elmt.attachEvent('onclick', Evlon.createDelegate(this, this.menu_onclick));
if (this.content.addEventListener)
this.content.addEventListener('click', function(){
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
},false
);
else if (this.content.attachEvent)
this.content.attachEvent('onclick', function(){
if(window.event)
{
window.event.cancelBubble = true;
window.event.returnValue = false;
}
}
);
var subMenus = Evlon.getChildren(this.content, { tagName: "LI" })
for (var i = 0; i < subMenus.length; ++i) {
var subMenu = subMenus[i];
this.subMenuItems.push(new Evlon.MenuItem(this, subMenu, menuItemFocusClassName));
}
this.getItemIndex = function()
{
for(var i = 0; i < this.menuWnd.menus.length; ++i)
{
if(this.menuWnd.menus[i] == this)
return i;
}
return -1;
}
}
Evlon.QQMenu = function(idMenu, menuFocusClassName, menuItemFocusClassName, defaultMenuIndex, defaultItemIndex, profile /*[{main:0,item:0},{main:1,item:0}]*/) {
this._menu = (typeof (idMenu) == 'string') ? document.getElementById(idMenu) : idMenu;
this.menus = [];
this.currentMenu = null;
this.currentMenuItem = null;
this.profile = {}; /* {menuIndex: itemIndex}*/
this.switchmenu = function(newmenu, defaultItemIndex) {
if (this.currentMenu != newmenu) {
if (this.currentMenu != null)
this.currentMenu.hide();
this.currentMenu = newmenu;
this.currentMenu.show(defaultItemIndex);
}
else {
this.currentMenu.toggle();
}
}
var childrens = Evlon.getChildren(this._menu, { tagName: 'LI' }); //.childNodes;
if (childrens.length > 0) {
for (var i = 0; i < childrens.length; ++i) {
var li = childrens[i];
var contents = Evlon.getChildren(li, { tagName: 'UL' });
if (contents.length != 1)
throw '必须只有一个子UL标签';
this.menus.push(new Evlon.MenuItemWrap(this, li, menuFocusClassName, contents[0], menuItemFocusClassName));
}
//变换配置
if(typeof(profile) == 'object')
{
for(var i = 0; i < profile.length; ++i)
{
this.profile[profile[i].main] = profile[i].item;
}
}
this.switchmenu(this.menus[defaultMenuIndex],defaultItemIndex);
}
}
Code
<ul id="menu" class="menu">
<li>分组一
<ul>
<li onclick="javascript:void(0);">菜单一</li>
<li onclick="javascript:void(0);">菜单二</li>
</ul>
</li>
<li>分组二
<ul>
<li onclick="javascript:void(0);">菜单一</li>
<li onclick="javascript:void(0);">菜单二</li>
</ul>
</li>
<li>分组三
<ul>
<li onclick="javascript:void(0);">菜单一</li>
<li onclick="javascript:void(0);">菜单二</li>
</ul>
</li>
</ul>
<script type="text/javascript>
var menu = new Evlon.QQMenu('menu' /*ul 的ID*/, 'menuhilight' /*分组高这样式 */ , 'hilight' /*菜单项高亮样式*/, def.main /*默认打开分组*/, def.item /*默认执行菜单项*/,[{main:0,item:0},{main:1,item:0}] /* 单击分组时,自动单击菜单项配置*/);
</script>
<ul id="menu" class="menu">
<li>分组一
<ul>
<li onclick="javascript:void(0);">菜单一</li>
<li onclick="javascript:void(0);">菜单二</li>
</ul>
</li>
<li>分组二
<ul>
<li onclick="javascript:void(0);">菜单一</li>
<li onclick="javascript:void(0);">菜单二</li>
</ul>
</li>
<li>分组三
<ul>
<li onclick="javascript:void(0);">菜单一</li>
<li onclick="javascript:void(0);">菜单二</li>
</ul>
</li>
</ul>
<script type="text/javascript>
var menu = new Evlon.QQMenu('menu' /*ul 的ID*/, 'menuhilight' /*分组高这样式 */ , 'hilight' /*菜单项高亮样式*/, def.main /*默认打开分组*/, def.item /*默认执行菜单项*/,[{main:0,item:0},{main:1,item:0}] /* 单击分组时,自动单击菜单项配置*/);
</script>