Main Points

Unobtrusive Javascript Example 5

This page is going to look like I'm taking a step backwards. It doesn't have the same functionality as Example 4, but we are in fact moving forward. In example 4, I was able to get two buttons to throw up two different menus. The functionality all worked with mouseovers and mouseouts, etc. However, I had the affected divs hard coded into the subroutines. In order to make the second button/menu set work, I had to copy and recode for the new divs. To extend this to four buttons like you see here would have doubled the file size again. Example 5 is where I'm confident enough that my menus function (after example 4) that I'm trying to create a generic subroutine, not hard coded, to reveal the menus.

This is a huge problem for adapting my script. The inline event handlers of my old script depended on passing a string argument (which not coincidentally was the id of the divs). So after beating my head against every syntax I could think of for the event handlers in an external script, I finally gave up on trying to pass arguments. Without being able to pass the arguments I hit a wall, until I found info on event sniffing and DOM id detection. This gave me a possible end run around the problem.

This script is my first and most basic effort to detect the id of the event and manipulate the id that triggered the action. If you can detect the id of the triggered element in the subroutine, you don't have to track it from the event handler. It seems inelegant to me, the element triggers the event, one event handler for each event...

document.getElementById("button01").onmouseover=ButtonOff;

Then you then lose it and have to go get it again in the middle of the subroutine. But it's my first attempt that uses one subroutine to cause a reaction in multiple elements. Even if it's a little weird.

function ButtonOff(e) {
// Opt out of browsers that don't support getElementById (or have it turned off)
if (!document.getElementById) return;

// Grab the XHTML id of the div triggered
if (!e) var e = window.event;

var item = (e.target) ? e.target.id : e.srcElement.id;

// Grab the Div
myDiv = document.getElementById(item);
myDiv.style.display="none";
}

Sweet! OK, this is really cutting edge stuff. I had to play with this for a little bit to figure out that it was in fact... actually working. Doesn't seem like it, does it? Seriously, try mousing over button 1, and tell me that you don't think there's an error on the page.

I tried to set a very simple function. No menus, just buttons. Mouseover the button and make it disappear, setting it's display to none. I didn't even bother to set code to bring it back. I just wanted make a button disappear and leave all other functions for the next example. Imagine my surprise when mousing over button 1 seemed to chain react and wipe out everything. It didn't take long to figure out what was wrong though. I thought the event handlers lines might be running all together. I changed their order, but it made no difference. The script behaved identically no matter the order. And if you mouse over button 4, it's the only one that disappears. If you mouseover any button, only the ones below it disappear. Consider that behavior, that's the key.

Since I'm reseting the display to none, the elements functionally disappear from the page. The page is relaid out as if the element didn't exist. Great in so far as it goes. However, that means that any button below the button you've moused over moves up... and suddenly you're moused over THAT one because THE BUTTON MOVED underneath your mouse. So now IT disappears. And then the one below it moves up, etc. Try mousing over button 1 quickly. If you can mouse out again fast enough, button 4 and maybe even three don't have time to disappear. So it works fine. It's just not very practical.

I also had FITS getting the thing to work in IE. It kept throwing an error. Turned out I had left out a var keyword. I thought Javascript was supposed to be weakly typed, but it sure wasn't in the case of trying to assign an object id to a variable in IE. It wanted that var explicitly. Then it worked fine.

var item = (e.target) ? e.target.id : e.srcElement.id;

On to example 6!

Skip to Main Points