This site outlines the problem clearly:
http://dynamic-tools.net/toolbox/isMouseLeaveOrEnter/
However, since we are using the wonderful prototype.js framework, we can solve this problem more elegantly than this site's authors did using just basic horrible Javascript.
To exhibit my solution to this problem, I have "borrowed" Joanna's site:
http://onepotcooking.com/amosbloomberg/f2008/class6/ecommerce/
If you check the Javascript, you will see I have added some code in the mouseout event handler of the product info divs. In the assignment, we said that when a user mouses out of a product info div, we should hide the div. However, the browser triggers those mouseout events far too often.
The browser thinks a user moused out of one of those divs even when a user mouses over any other element within one of those divs. So we get a flickering effect as the mouseout event handlers hide the divs, and the mouseover event handlers on the thumbnail images immediately show them again. On off on off on off on off, etc.
To solve this, we don't just hide the product info div when the mouseout event is triggered. We first check to make sure the user really moused off of the product info div before hiding it. To do this we check the "relatedTarget" of the mouseout event and make sure it is not a child of the product info div.
The relatedTarget property of any mouseover or mouseout event in Javascript is a built-in property in all Javascript, not just in prototype.js. For mouseover events, it holds the element that the user just left. In the case of mouseout events, it holds the element that the user is going to.
So we chek this relatedTarget element for the mouseout events. If it is a child of the product info div that triggered the mouseout event, we don't hide the product info div. If it's not a child of the product info div, we do hid that div.
All this in a few lines of code, thanks to prototype.js's childOf() function that easily allows us to check whether one element is a child of another element.
Here's the relevant code:
//whenever a user user mouses over the container div, call an event handler
Event.observe(el, 'mouseout', function(evt) {
//regular javascript mouseover and mouseout events automatically have a property "relatedTarget"
//in the case of mouseover events, this property holds the element that user came from before they moused over this element
//in the case of mouseout events, this property holds the element that the user went to after they left this element
var relTarg = $(evt.relatedTarget); //get the relatedTarget for this event, and make sure it has all the nice prototype.js extra functions
//if the relatedTarget is not a child of the current element, and it is not the same element as the current element, hide the product info divs
if (!relTarg.childOf(el) && !(relTarg == el)) {
//prototype.js provides a nice function "childOf()" to check if one element is a child element of another element
//in this case, we've checked to make sure the relatedTarget is not a child of the element that triggered the mouseout event
hideAllContent();
}
});
No comments:
Post a Comment