2009-08-08 9 views
1

J'essaie de faire dérouler le menu horizontal en javascript. Cela fonctionne bien sur Firefox et Chrome, mais me donne des problèmes dans IE.attachEvent donne des problèmes

Voici le code que j'ai

function init(){ 

    hideAllSubMenu(); 

    var menuItem = document.getElementById("menu_wrap").getElementsByTagName("div"); 

    for(var index = 0; index < menuItem.length; index++) 
    { 
     // if firefox and all oother browsers 
     if(typeof menuItem[index].addEventListener != "undefined") 
     { 
      menuItem[index].addEventListener("mouseover", ShowListener, false); 
      menuItem[index].addEventListener("click", ShowListener, false); 
     } 
     else //IE 
     { 
      menuItem[index].attachEvent("onclick", ShowListener); 
      menuItem[index].attachEvent("onmouseover", ShowListener); 
     }  
    } 
} 


function ShowListener(event) 
{ 
    hideAllSubMenu(); 

    var menuItemIdStr = this.id; 
    var menuItemIdNum = menuItemIdStr.replace(/menu/i, ""); 
    var subMenu = document.getElementById("submenu_wrap" + menuItemIdNum); 

    subMenu.style.left = this.offsetLeft + "px"; 
    subMenu.style.top = this.offsetTop + this.offsetHeight + 2 + "px"; 
    subMenu.style.display = "block"; 
} 

Il est semble comme se plaindre de son cette. Je comprends que dans la fonction écouteur d'événement IE n'est pas une copie, mais une référence, et c'est pourquoi ce ce qui me pose un problème. Y a-t-il un moyen de contourner ce problème?

J'ai même essayé de créer une fonction séparée pour attachEvent pour IE et l'objet chemin d'accès directement, mais il se plaint encore.

Quelque chose comme ça

menuItem[index].attachEvent("onmouseover", ShowListenerIE(menuItem[index])); 

Note: Je ne l'intention de réécrire ce menu simple fonction de JQuery, mais pour l'instant je suis intéressé par JavaScript apprentissage de base + DOM, et je voudrais trouver un moyen de ce problème.

Merci d'avance.

Répondre

3

La cible d'un événement dans IE se trouve dans event.srcElement et vous pouvez obtenir des informations similaires dans d'autres navigateurs à partir de event.target. Notez également que IE ne transmettra pas d'événement en tant qu'argument au gestionnaire - il s'agit plutôt de window.event. Ainsi, une solution complète:

if (!event) 
{ 
    event = window.event; //IE 
} 

var target; 
if (event.target) 
{ 
    target = event.target; 
} 
else if (event.srcElement) 
{ 
    target = event.srcElement; 
} 

//From here on is your code, use target instead of this 

Voir here pour plus de détails gores. Disclaimer: mon code n'a pas été testé.

+0

Je suis allé à la fin avec la cible var = event.srcElement? event.srcElement: event.target; Je n'ai pas testé ce que vous me donnez, mais votre solution semble être celle qui fonctionnerait – Dmitris

+1

Si vous voulez réellement que le contexte de "ceci" pour le gestionnaire d'événements soit défini sur l'objet sur lequel vous avez appelé la fonction, vous devra utiliser la méthode "call" ou "apply" avec une fonction qui renvoie une fermeture. par exemple. menuItem [index] .attachEvent ("onclick", fonction (obj) { return function() { ShowListener.call (obj); }; } (menuItem [index])); – Alex

3

En complément des réponses ci-dessus, j'utilise généralement cette façon de coder plus JavaScript-y:

function eventHandler(event){ 
    var event = window.event || event; 
    var target = event.srcElement || event.target; 
} 
Questions connexes