From 667b07d9628b88b8b203d3635c92426159f14876 Mon Sep 17 00:00:00 2001 From: Noah Sloan Date: Wed, 5 Dec 2012 16:05:39 -0600 Subject: [PATCH] Force hover leave on new mouseenter. Fixes #63 and #64. If the mouse has entered a new element, this change forces the hoverleave event to fire on the previously hovered element, even if no mouseleave event fires. The mouseleave event will not fire if the element is removed while hovered and possibly in other circumstances. --- event/hover/hover.js | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/event/hover/hover.js b/event/hover/hover.js index 7cf2d0d9..2e084173 100644 --- a/event/hover/hover.js +++ b/event/hover/hover.js @@ -110,11 +110,28 @@ steal('jquery', 'jquery/event/livehack', function ($) { // now start checking mousemoves to update location var delegate = ev.delegateTarget || ev.currentTarget; var selector = ev.handleObj.selector; + var pending = $.data(delegate,"_hover"+selector); // prevents another mouseenter until current has run its course - if ($.data(delegate, "_hover" + selector)) { + if(pending) { + // Under some circumstances, mouseleave may never fire + // (e.g., the element is removed while hovered) + // so if we've entered another element, wait the leave time, + // then force it to release. + if(!pending.forcing) { + pending.forcing = true; + clearTimeout(pending.leaveTimer); + var leaveTime = pending.leaving ? + Math.max(0,pending.hover.leave - (new Date() - pending.leaving)) : + pending.hover.leave; + var self = this; + + setTimeout(function() { + pending.callHoverLeave(); + onmouseenter.call(self,ev); + },leaveTime); + } return; } - $.data(delegate, "_hover" + selector, true) var loc = { pageX : ev.pageX, pageY : ev.pageY @@ -158,7 +175,8 @@ steal('jquery', 'jquery/event/livehack', function ($) { } else { clearTimeout(leaveTimer); // leave the hover after the time set in hover.leave(time) - leaveTimer = setTimeout(function () { + pending.leaving = new Date(); + leaveTimer = pending.leaveTimer = setTimeout(function(){ callHoverLeave(); }, hover._leave) } @@ -178,6 +196,11 @@ steal('jquery', 'jquery/event/livehack', function ($) { }) hovered = true; }; + pending = { + callHoverLeave: callHoverLeave, + hover: hover + }; + $.data(delegate,"_hover"+selector, pending); // Bind the mousemove event $(enteredEl).bind("mousemove", mousemove).bind("mouseleave", mouseleave);