views:

285

answers:

2

Hello everybody.

I am trying to do drop down horizontal menu in javascript. It's works fine on Firefox and Chrome, however giving me troubles in IE.

Here is the code i have

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";
}

It's seems like its complaining about this. I understand that in IE event listener function is not copy but a reference, and thats why this giving me a problem. Is there a way around this problem ?

I even tried to create separate function for attachEvent for IE and path there object directly, however it still complaining.

Something like that

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

Note: I do plan to rewrite this simple menu in feature to JQuery, but for now I am interested in learning JavaScript Core + DOM, and would like to find a way around this problem.

Thanks in advance.

+2  A: 

The target of an event in IE is in event.srcElement, and you can get similar information in other browsers from event.target. Note also that IE won't pass event as an argument to the handler - it's in window.event instead. So, a complete solution:

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

See http://www.quirksmode.org/js/events_properties.html#target for more gory details. Disclaimer: my code is untested.

Matt
I went at the end with the var target = event.srcElement ? event.srcElement : event.target;I did not test what you give me, but but your solution seems like one that would work
Dmitris
If you do actually want the context of "this" for the event handler to be set to the object you called the function on, you will need to use the "call" or "apply" method with a function which returns a closure.e.g.menuItem[index].attachEvent("onclick", function (obj) { return function () { ShowListener.call(obj); };} (menuItem[index]));
Alex
A: 

As an addition to the answers above, I generally use this way of coding more JavaScript-y:

function eventHandler( event ){
    var event  = window.event || event;
    var target = event.srcElement || event.target;
}
Mehmet Duran