DHTML Lab: Cross-Browser Hierarchical Menus; Explorer Events
Cross-Browser Hierarchical Menus
| |||
FAIR Trick Question: Experts Clear |
Events, Events, EverywhereOur single item example menu in the left column now has the triangle image added. Pass your mouse over the menu, making sure you pass over the image. What are the results? Now open the regular popup menus to the left. Pass over the image. What happens to the item highlight? In the last two pages, we have used a different script than our final one. One that omits the statements that we will discuss and add on this page. On the previous page, the child menu overlap covered the image, ergo the "unfair" trick question. Using what we learned on the previous page, we know that:
Point 5, above, demonstrates another important difference between Navigator and Explorer. Navigator considers the document elements in mathematical abstraction. It knows the menu element is there, and that it is enclosing the item, making it 'larger,' even though it occupies the same space as the item. In the same way, we spend hours discussing no-dimensional "points" and one-dimensional "lines" in math class, even though they are invisible. As authors, we know the menu element is there. We put it there! Explorer considers only the elements that occupy the page's two dimensional space. This ability to overlook elements is compensated for by the transference of event handling to contained elements. Scripted correctly, the event handlers can still handle statements meant for the overlooked outer element, as demonstrated by the functions on the previous page. This two dimensional approach is also illustrated by the firing of the item's onmouseout when we mouse onto the image. Why does it fire? We are not leaving the item. We are still on it. If we are over more than one element simultaneously, (eg. menu/item/image) the one lowest in the hierarchy is the source, or current, element. Explorer considers us to have "left" the enclosing element, to have moused out of it. If not understood and scripted correctly, this behaviour could be disasterous. When we mouse over the image, we are first mousing out of the item which calls itemOut(), and menuOut(). Then we mouse over the image, which calls itemOver(), and menuOver(). This leads to the background color "blinking", and if we did not use timers for menu hiding, it would cause the collapse of the menu tree, as well. New Properties to the Rescue...Luckily, Explorer provides two new properties of the event object, fromElement and toElement, to assist us with mouseover and mouseout event handling. On a mouseover or a mouseout, event.fromElement is the element we are coming from, and event.toElement is the element we are moving to. Do not confuse either of these properties with event.srcElement, which stores the element that fired the event handler. Given Explorer's generous distribution of event handling, the source element could be a dozen or more elements removed from the actual elements involved in the mouse action. ...and a New MethodExplorer 4 has also introduced a powerful method: contains(), for use with conditional statements. The syntax is: BooleanVariable = containingElement.contains(childElement);or: if (containingElement.contains(childElement)) { statements to execute } Needless to say, it checks whether one element is contained within another, returning true if it is, false if it isn't. Let's modify the mouse event functions to avoid unwanted behaviour, using the new properties, the new method, and our old friend srcElement. The OVER FunctionsWhen we mouse over an image, we do not want the itemOver() function called superfluously, so we exclude the image from executing the function by including this statement as the first line: if (IE4 && event.srcElement.tagName == "IMG") return; The above reads: If this is Explorer and the event was generated by an image, return from the function. Our itemOver() function becomes: function itemOver(){ if (IE4 && event.srcElement.tagName == "IMG") return; if (NS4) { this.bgColor = overCol; } else { this.style.backgroundColor = overCol; this.style.color = overFnt; } if (this.container.hasChildVisible) { this.container.hideChildren(this); } if(this.hasMore) { if (NS4) { this.childY = this.pageY + childOffset; this.childX = (keep with next line) this.container.left + (menuWidth - childOverlap); } else { this.childY = (keep with next line) this.style.pixelTop + this.container.style.pixelTop + childOffset; this.childX = (keep with next line) this.container.style.pixelLeft + (menuWidth - childOverlap); } this.child.moveTo(this.childX,this.childY); this.child.keepInWindow(); this.container.hasChildVisible = true; this.container.visibleChild = this.child; this.child.showIt(true); } } The menuOver() function call from the image is harmless, so that function remains the same. function menuOver() { this.isOn = true; isOverMenu = true; currentMenu = this; if (this.hideTimer) clearTimeout(this.hideTimer); } The OUT FunctionsThe only case where the menuOut() should not be allowed to fire is when we mouse from an item to a contained image. In otherwords, when the source element contains the to element. function menuOut() { if (IE4 && event.srcElement.contains(event.toElement)) return; this.isOn = false; isOverMenu = false; if (IE4) allTimer = setTimeout("currentMenu.hideTree()",10); } Finally, we update itemOut(), the function responsible for the background color flickering. We don't want itemOut() to be executed in these cases:
function itemOut(){ if (IE4 && (event.srcElement.contains(event.toElement) || (event.fromElement.tagName=="IMG" && (keep with next line) event.toElement.contains(event.fromElement)))) return; if (NS4) { this.bgColor = backCol; if (!isOverMenu) { allTimer = setTimeout("currentMenu.hideTree()",10); } } else { this.style.backgroundColor = backCol; this.style.color = fntCol; } } We have now included the minimum checks necessary to avoid unwanted menu behaviour, and learned a bit about Explorer events along the way, hopefully. Let's tidy up loose ends with a refresher of the hide routines. |
Produced by Peter Belesis and
All Rights Reserved. Legal Notices.Created: Feb. 27, 1998
Revised: Feb. 27, 1998
URL: https://www.webreference.com/dhtml/column15/menu2IEvents.html