aboutsummaryrefslogtreecommitdiffstats
path: root/src/jqLite.js
diff options
context:
space:
mode:
authorgockxml2013-04-29 18:14:40 +0100
committerPete Bacon Darwin2013-04-29 18:26:32 +0100
commit06f2b2a8cf7e8216ad9ef05f73426271c2d97faa (patch)
treee9890deaf8d9f4f66868df33cda43cb9ec34585a /src/jqLite.js
parent0985a37376314616ac2b777bddd8bc07e1be7af7 (diff)
downloadangular.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.js48
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] = [];