Revision: 13589
Updated Code
at April 28, 2009 14:59 by pdswan
Updated Code
(function(){ function firstCommonAncestor(elm1, elm2){ var p = elm1.up(); while( !elm2.descendantOf(p) ){ p = p.up(); } return p; } function stopEvent(e){ try{ e.stop(); }catch(ex){} } Event.observe(document, 'mouseout', function(e){ var from = e.element(); var to = e.relatedTarget; p = null; if ( !to || (from !== to && !to.descendantOf(from))) { /* mouseleave should bubble up until the to element because we have left all elements up to that one */ var stopOn = null; if( to ){ if( from.descendantOf(to) ){ stopOn = to.childElements(); }else{ p = firstCommonAncestor(from, to); if( p && to.descendantOf(p) ){ stopOn = p.childElements(); } } } if( stopOn ){ stopOn.invoke('observe', 'custom:mouseleave', stopEvent); } from.fire('custom:mouseleave'); if( stopOn ){ stopOn.invoke('stopObserving', 'custom:mouseleave', stopEvent); } } var p = null; if( to && !from.descendantOf(to)){ /* mouseenter can bubble, no problem! */ var stopOn = null; if( to.descendantOf(from)){ stopOn = from.childElements(); }else{ // do first common ancestor's children, see below. p = firstCommonAncestor(to, from); stopOn = p.childElements(); } if( stopOn ){ stopOn.invoke('observe', 'custom:mouseenter', stopEvent); } to.fire('custom:mouseenter'); if( stopOn ){ stopOn.invoke('stopObserving', 'custom:mouseenter', stopEvent); } } }); })();
Revision: 13588
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at April 28, 2009 14:39 by pdswan
Initial Code
(function(){ function firstCommonAncestor(elm1, elm2){ var p = elm1.up(); while( !elm2.descendantOf(p) ){ p = p.up(); } return p; } function stopEvent(e){ try{ e.stop(); }catch(ex){} } Event.observe(document, 'mouseout', function(e){ var from = e.element(); var to = e.relatedTarget; var p = null; if( to && !from.descendantOf(to)){ /* mouseenter can bubble, no problem! */ var stopOn = null; if( to.descendantOf(from)){ stopOn = from.childElements(); }else{ // do first common ancestor's children, see below. p = firstCommonAncestor(to, from); stopOn = p.childElements(); } if( stopOn ){ stopOn.invoke('observe', 'custom:mouseenter', stopEvent); } to.fire('custom:mouseenter'); if( stopOn ){ stopOn.invoke('stopObserving', 'custom:mouseenter', stopEvent); } } p = null; if ( !to || (from !== to && !to.descendantOf(from))) { /* mouseleave should bubble up until the to element because we have left all elements up to that one */ var stopOn = null; if( to ){ if( from.descendantOf(to) ){ stopOn = to.childElements(); }else{ p = firstCommonAncestor(from, to); if( p && to.descendantOf(p) ){ stopOn = p.childElements(); } } } if( stopOn ){ stopOn.invoke('observe', 'custom:mouseleave', stopEvent); } from.fire('custom:mouseleave'); if( stopOn ){ stopOn.invoke('stopObserving', 'custom:mouseleave', stopEvent); } } }); })();
Initial URL
Initial Description
since the script observes mouseout, it should fire mouseleave events before mouseenter to preserve correct order.
Initial Title
Prototype custom event mouseenter mouseleave implementation
Initial Tags
javascript, event
Initial Language
JavaScript