2010-04-09 38 views
0

下面的代碼在嵌套列表項目序列上創建一個漂亮的彈出菜單動作。面臨的挑戰是我需要更改由鼠標懸停觸發彈出窗口的默認行爲,以便您必須單擊才能觸發彈出。轉換彈出菜單以響應onclick vs mouseover

理想情況下,我只想修改此代碼,以便您點擊位於菜單項右側的小圖標(加號/減號)(如果它有子菜單)。有人可以給我一些指導,說明我需要改變以實現這一點嗎?

/* a few sniffs to circumvent known browser bugs */ 
var sUserAgent = navigator.userAgent.toLowerCase(); 
var isIE=document.all?true:false; 
var isNS4=document.layers?true:false; 
var isOp=(sUserAgent.indexOf('opera')!=-1)?true:false; 
var isMac=(sUserAgent.indexOf('mac')!=-1)?true:false; 
var isMoz=(sUserAgent.indexOf('mozilla/5')!=-1&&sUserAgent.indexOf('opera')==-1&&sUserAgent.indexOf('msie')==-1)?true:false; 
var isNS6=(sUserAgent.indexOf('netscape6')!=-1&&sUserAgent.indexOf('opera')==-1&&sUserAgent.indexOf('msie')==-1)?true:false; 
var dom=document.getElementById?true:false; 

/* sets time until menus disappear in milliseconds */ 
var iMenuTimeout=1500; 

var aMenus=new Array; 
var oMenuTimeout; 
var iMainMenusLength=0; 

/* the following boolean controls the z-index property if needed */ 
/* if is only necessary if you have multiple mainMenus in one file that are overlapping */ 
/* set bSetZIndeces to true (either here or in the HTML) and the main menus will have a z-index set in descending order so that preceding ones can overlap */ 
/* the integer iStartZIndexAt controls z-index of the first main menu */ 
var bSetZIndeces=true; 
var iStartZIndexAt=1000; 
var aMainMenus=new Array; 

/* load up the submenus */ 
function loadMenus(){ 
    if(!dom)return; 
    var aLists=document.getElementsByTagName('ul'); 
    for(var i=0;i<aLists.length;i++){ 
     if(aLists[i].className=='navMenu')aMenus[aMenus.length]=aLists[i]; 
    } 
    var aAnchors=document.getElementsByTagName('a'); 
    var aItems = new Array; 
    for(var i=0;i<aAnchors.length;i++){ 
//  if(aAnchors[i].className=='navItem')aItems[aItems.length] = aAnchors[i]; 
     aItems[aItems.length] = aAnchors[i]; 
    } 
    var sMenuId=null; 
    var oParentMenu=null; 
    var aAllElements=document.body.getElementsByTagName("*"); 
    if(isIE)aAllElements=document.body.all; 
    /* loop through navItem and navMenus and dynamically assign their IDs */ 
    /* each relies on it's parent's ID being set before it */ 
    for(var i=0;i<aAllElements.length;i++){ 
     if(aAllElements[i].className.indexOf('x8menus')!=-1){ 
      /* load up main menus collection */ 
      if(bSetZIndeces)aMainMenus[aMainMenus.length]=aAllElements[i]; 
     } 
//  if(aAllElements[i].className=='navItem'){ 
     if(aAllElements[i].tagName=='A'){ 
      oParentMenu = aAllElements[i].parentNode.parentNode; 
      if(!oParentMenu.childMenus) oParentMenu.childMenus = new Array; 
      oParentMenu.childMenus[oParentMenu.childMenus.length]=aAllElements[i]; 
      if(aAllElements[i].id==''){ 
       if(oParentMenu.className=='x8menus'){ 
        aAllElements[i].id='navItem_'+iMainMenusLength; 
        //alert(aAllElements[i].id); 
        iMainMenusLength++; 
       }else{ 
        aAllElements[i].id=oParentMenu.id.replace('Menu','Item')+'.'+oParentMenu.childMenus.length; 
       } 
      } 
     } else if(aAllElements[i].className=='navMenu'){ 
      oParentItem = aAllElements[i].parentNode.firstChild; 
      aAllElements[i].id = oParentItem.id.replace('Item','Menu'); 
     } 
    } 
    /* dynamically set z-indeces of main menus so they won't underlap */ 
    for(var i=aMainMenus.length-1;i>=0;i--){ 
     aMainMenus[i].style.zIndex=iStartZIndexAt-i; 
    } 
    /* set menu item properties */ 
    for(var i=0;i<aItems.length;i++){ 
     sMenuId=aItems[i].id; 
     sMenuId='navMenu_'+sMenuId.substring(8,sMenuId.lastIndexOf('.')); 
     /* assign event handlers */ 
     /* eval() used here to avoid syntax errors for function literals in Netscape 3 */ 
     eval('aItems[i].onmouseover=function(){modClass(true,this,"activeItem");window.clearTimeout(oMenuTimeout);showMenu("'+sMenuId+'");};'); 
     eval('aItems[i].onmouseout=function(){modClass(false,this,"activeItem");window.clearTimeout(oMenuTimeout);oMenuTimeout=window.setTimeout("hideMenu(\'all\')",iMenuTimeout);}'); 
     eval('aItems[i].onfocus=function(){this.onmouseover();}'); 
     eval('aItems[i].onblur=function(){this.onmouseout();}'); 
     //aItems[i].addEventListener("keydown",function(){keyNav(this,event);},false); 
    } 
    var sCatId=0; 
    var oItem; 
    for(var i=0;i<aMenus.length;i++){ 
     /* assign event handlers */ 
     /* eval() used here to avoid syntax errors for function literals in Netscape 3 */ 
     eval('aMenus[i].onmouseover=function(){window.clearTimeout(oMenuTimeout);}'); 
     eval('aMenus[i].onmouseout=function(){window.clearTimeout(oMenuTimeout);oMenuTimeout=window.setTimeout("hideMenu(\'all\')",iMenuTimeout);}'); 
     sCatId=aMenus[i].id; 
     sCatId=sCatId.substring(8,sCatId.length); 
     oItem=document.getElementById('navItem_'+sCatId); 
     if(oItem){ 
      if(!isOp && !(isMac && isIE) && oItem.parentNode)modClass(true,oItem.parentNode,"hasSubMenu"); 
      else modClass(true,oItem,"hasSubMenu"); 
      /* assign event handlers */ 
      eval('oItem.onmouseover=function(){window.clearTimeout(oMenuTimeout);showMenu("navMenu_'+sCatId+'");}'); 
      eval('oItem.onmouseout=function(){window.clearTimeout(oMenuTimeout);oMenuTimeout=window.clearTimeout(oMenuTimeout);oMenuTimeout=window.setTimeout(\'hideMenu("navMenu_'+sCatId+'")\',iMenuTimeout);}'); 
      eval('oItem.onfocus=function(){window.clearTimeout(oMenuTimeout);showMenu("navMenu_'+sCatId+'");}'); 
      eval('oItem.onblur=function(){window.clearTimeout(oMenuTimeout);oMenuTimeout=window.clearTimeout(oMenuTimeout);oMenuTimeout=window.setTimeout(\'hideMenu("navMenu_'+sCatId+'")\',iMenuTimeout);}'); 
      //oItem.addEventListener("keydown",function(){keyNav(this,event);},false); 
     } 
    } 
} 

/* this will append the loadMenus function to any previously assigned window.onload event */ 
/* if you reassign this onload event, you'll need to include this or execute it after all the menus are loaded */ 
function newOnload(){ 
    if(typeof previousOnload=='function')previousOnload(); 
    loadMenus(); 
} 
var previousOnload; 
if(window.onload!=null)previousOnload=window.onload; 
window.onload=newOnload; 

/* show menu and hide all others except ancestors of the current menu */ 
function showMenu(sWhich){ 
    var oWhich=document.getElementById(sWhich); 
    if(!oWhich){ 
     hideMenu('all'); 
     return; 
    } 
    var aRootMenus=new Array; 
    aRootMenus[0]=sWhich 
    var sCurrentRoot=sWhich; 
    var bHasParentMenu=false; 
    if(sCurrentRoot.indexOf('.')!=-1){ 
     bHasParentMenu=true; 
    } 
    /* make array of this menu and ancestors so we know which to leave exposed */ 
    /* ex. from ID string "navMenu_12.3.7.4", extracts menu levels ["12.3.7.4", "12.3.7", "12.3", "12"] */ 
    while(bHasParentMenu){ 
     if(sCurrentRoot.indexOf('.')==-1)bHasParentMenu=false; 
     aRootMenus[aRootMenus.length]=sCurrentRoot; 
     sCurrentRoot=sCurrentRoot.substring(0,sCurrentRoot.lastIndexOf('.')); 
    } 
    for(var i=0;i<aMenus.length;i++){ 
     var bIsRoot=false; 
     for(var j=0;j<aRootMenus.length;j++){ 
      var oThisItem=document.getElementById(aMenus[i].id.replace('navMenu_','navItem_')); 
      if(aMenus[i].id==aRootMenus[j])bIsRoot=true; 
     } 
     if(bIsRoot && oThisItem)modClass(true,oThisItem,'hasSubMenuActive'); 
     else modClass(false,oThisItem,'hasSubMenuActive'); 
     if(!bIsRoot && aMenus[i].id!=sWhich)modClass(false,aMenus[i],'showMenu'); 
    } 
    modClass(true,oWhich,'showMenu'); 
    var oItem=document.getElementById(sWhich.replace('navMenu_','navItem_')); 
    if(oItem)modClass(true,oItem,'hasSubMenuActive'); 
} 

function hideMenu(sWhich){ 
    if(sWhich=='all'){ 
     /* loop backwards b/c WinIE6 has a bug with hiding display of an element when it's parent is already hidden */ 
     for(var i=aMenus.length-1;i>=0;i--){ 
      var oThisItem=document.getElementById(aMenus[i].id.replace('navMenu_','navItem_')); 
      if(oThisItem)modClass(false,oThisItem,'hasSubMenuActive'); 
      modClass(false,aMenus[i],'showMenu'); 
     } 
    }else{ 
     var oWhich=document.getElementById(sWhich); 
     if(oWhich)modClass(false,oWhich,'showMenu'); 
     var oThisItem=document.getElementById(sWhich.replace('navMenu_','navItem_')); 
     if(oThisItem)modClass(false,oThisItem,'hasSubMenuActive'); 
    } 
} 

/* add or remove element className */ 
function modClass(bAdd,oElement,sClassName){ 
    if(bAdd){/* add class */ 
     if(oElement.className.indexOf(sClassName)==-1)oElement.className+=' '+sClassName; 
    }else{/* remove class */ 
     if(oElement.className.indexOf(sClassName)!=-1){ 
      if(oElement.className.indexOf(' '+sClassName)!=-1)oElement.className=oElement.className.replace(' '+sClassName,''); 
      else oElement.className=oElement.className.replace(sClassName,''); 
     } 
    } 
    return oElement.className; /* return new className */ 
} 

//document.body.addEventListener("keydown",function(){keyNav(event);},true); 

function setBubble(oEvent){ 
    oEvent.bubbles = true; 
} 

function keyNav(oElement,oEvent){ 
    alert(oEvent.keyCode); 
    window.status=oEvent.keyCode; 
    return false; 
} 

回答

0
var isMac=(sUserAgent.indexOf('mac')!=-1)?true:false; 

哦,不!瀏覽器嗅探的恐怖。古代瀏覽器嗅探着這一點。並且完全不可靠的瀏覽器嗅探,甚至可以通過瀏覽器嗅探的低,低標準來啓動。而有人不瞭解布爾值。輝煌。

eval('aItems[i].onmouseover=function(){modClass(true,this,"activeItem");window.clearTimeout(oMenuTimeout);showMenu("'+sMenuId+'");};'); 

KILL用火

好了,這就是你一點會改變說onclick,而不是onmouseover。而其他onmouseovershowMenu進一步下跌。但可能不是中間那個。

但是真的。殺了它。最好用火。

/* eval() used here to avoid syntax errors for function literals in Netscape 3 */ 

Netscape 3!大聲笑。一個實際的LOL。我不只是在輸入「LOL」,我是LOLling。大聲笑。

此腳本沒有兌換功能。這是另一個(無限糟糕)年齡的人造物。令人驚訝的是,它甚至還在運行。扔掉它並重新開始。

有許多現有的庫,框架和插件將用幾個類和調用行代替這個可怕的混亂。

+0

@bobince>您提出了一些非常好的觀點,我應該在說明中介紹。該腳本是遺留應用程序的一部分,不容易更改。我只是想把一點口紅放在豬身上。 – 2010-04-09 16:09:23