diff options
| author | gockxml | 2013-04-29 18:14:40 +0100 | 
|---|---|---|
| committer | Pete Bacon Darwin | 2013-04-29 18:26:32 +0100 | 
| commit | 06f2b2a8cf7e8216ad9ef05f73426271c2d97faa (patch) | |
| tree | e9890deaf8d9f4f66868df33cda43cb9ec34585a /src/jqLite.js | |
| parent | 0985a37376314616ac2b777bddd8bc07e1be7af7 (diff) | |
| download | angular.js-06f2b2a8cf7e8216ad9ef05f73426271c2d97faa.tar.bz2 | |
fix(jqLite): correct implementation of mouseenter/mouseleave event
Implement mouseenter/mouseleave event referring to
http://www.quirksmode.org/js/events_mouse.html#link8 and jQuery source
code(not dependent on jQuery).
The old implementation is wrong. When moving mouse from a parent element
into a child element, it would trigger mouseleave event, which should not.
And the old test about mouseenter/mouseleave is wrong too. It just
triggers mouseover and mouseout events, cannot describe the process of mouse
moving from one element to another element, which is important for
mouseenter/mouseleave.
Closes #2131, #1811
Diffstat (limited to 'src/jqLite.js')
| -rw-r--r-- | src/jqLite.js | 48 | 
1 files changed, 34 insertions, 14 deletions
| diff --git a/src/jqLite.js b/src/jqLite.js index cf63c5df..0abae3d7 100644 --- a/src/jqLite.js +++ b/src/jqLite.js @@ -607,23 +607,43 @@ forEach({        if (!eventFns) {          if (type == 'mouseenter' || type == 'mouseleave') { -          var counter = 0; +          var contains = document.body.contains || document.body.compareDocumentPosition ? +          function( a, b ) { +            var adown = a.nodeType === 9 ? a.documentElement : a, +            bup = b && b.parentNode; +            return a === bup || !!( bup && bup.nodeType === 1 && ( +              adown.contains ? +              adown.contains( bup ) : +              a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 +              )); +            } : +            function( a, b ) { +              if ( b ) { +                while ( (b = b.parentNode) ) { +                  if ( b === a ) { +                    return true; +                  } +                } +              } +              return false; +            };	 -          events.mouseenter = []; -          events.mouseleave = []; +          events[type] = []; +		 +		  // Refer to jQuery's implementation of mouseenter & mouseleave +          // Read about mouseenter and mouseleave: +          // http://www.quirksmode.org/js/events_mouse.html#link8 +          var eventmap = { mouseleave : "mouseout", mouseenter : "mouseover"}           +          bindFn(element, eventmap[type], function(event) { +            var ret, target = this, related = event.relatedTarget; +            // For mousenter/leave call the handler if related is outside the target. +            // NB: No relatedTarget if the mouse left/entered the browser window +            if ( !related || (related !== target && !contains(target, related)) ){ +              handle(event, type); +            }	 -          bindFn(element, 'mouseover', function(event) { -            counter++; -            if (counter == 1) { -              handle(event, 'mouseenter'); -            } -          }); -          bindFn(element, 'mouseout', function(event) { -            counter --; -            if (counter == 0) { -              handle(event, 'mouseleave'); -            }            }); +          } else {            addEventListenerFn(element, type, handle);            events[type] = []; | 
