Using version r5 of hoverIntent. It doesn't work as an event like the original code did, so I had to doctor it up a bit. It works OK with firefox, but not with IE. I have a possible patch to apply after I check this in.

git-svn-id: file:///svn-source/pmgr/branches/pre_0.1_work_20090819@820 97e9348a-65ac-dc4b-aefc-98561f571b83
This commit is contained in:
abijah
2009-08-29 18:14:18 +00:00
parent bf8aaea041
commit cea9332ac6

View File

@@ -1,57 +1,147 @@
/* ****************************************************************************** /**
* hoverintent * hoverIntent is similar to jQuery's built-in "hover" function except that
* * instead of firing the onMouseOver event immediately, hoverIntent checks
* Works like mouseover, but instead of firing immediately when an object * to see if the user's mouse has slowed down (beneath the sensitivity
* is mouseover'ed, it tries to determine when the user actually _intends_ * threshold) before firing the onMouseOver event.
* to have the pointer hover over the object. In other words, it's a lot *
* like mouseover with a delay before firing, and if the pointer moves * hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* before hoverintent can fire, it doesn't fire at all. * <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* *
* Found from jQuery UI Ticket #3614 * hoverIntent is currently available for use in all personal or commercial
* http://dev.jqueryui.com/ticket/3614 * projects under both MIT and GPL licenses. This means that you can choose
*/ * the license that best suits your project, and use it accordingly.
*
var cfg = ($.hoverintent = { * // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
sensitivity: 7, * $("ul li").hoverIntent( showNav , hideNav );
interval: 100 *
}); * // advanced usage receives configuration object only
* $("ul li").hoverIntent({
$.event.special.hoverintent = { * sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
setup: function() { * interval: 100, // number = milliseconds of polling interval
$(this).bind("mouseover", jQuery.event.special.hoverintent.handler); * over: showNav, // function = onMouseOver callback (required)
}, * timeout: 0, // number = milliseconds delay before onMouseOut function call
teardown: function() { * out: hideNav // function = onMouseOut callback (required)
$(this).unbind("mouseover", jQuery.event.special.hoverintent.handler); * });
}, *
handler: function(event) { * @param f onMouseOver function || An object with configuration options
event.type = "hoverintent"; * @param g onMouseOut function || Nothing (use configuration options object)
var self = this, * @author Brian Cherne <brian@cherne.net>
args = arguments, */
target = $(event.target), (function($) {
cX, cY, pX, pY; $.fn.hoverIntent = function(f,g) {
// default configuration options
var cfg = {
function track(event) { sensitivity: 7,
cX = event.pageX; interval: 100,
cY = event.pageY; timeout: 0
}; };
pX = event.pageX; // override configuration options with user supplied object
pY = event.pageY; cfg = $.extend(cfg, g ? { over: f, out: g } : f );
function clear() {
target.unbind("mousemove", track).unbind("mouseout", arguments.callee); $('#debug').append('Setup hoverIntent<BR>');
clearTimeout(timeout);
} // instantiate variables
function handler() { // cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// A private function for getting mouse position
var track = function(ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for comparing current and previous mouse position
var compare = function(ev,ob) {
$('#debug').append('handle timeout<BR>');
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) { if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
clear(); $(ob).unbind("mousemove",track);
jQuery.event.handle.apply(self, args); // set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
$('#debug').append('fire over<BR>');
//$('#debug').append(dump(ev));
return cfg.over.apply(ob,[ev]);
} else { } else {
// set previous coordinates for next time
pX = cX; pY = cY; pX = cX; pY = cY;
timeout = setTimeout(handler, cfg.interval); // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
} }
} };
var timeout = setTimeout(handler, cfg.interval);
target.mousemove(track).mouseout(clear); // A private function for delaying the mouseOut function
return true; var delay = function(ev,ob) {
} ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
$('#debug').append('fire out<BR>');
return cfg.out.apply(ob,[ev]);
};
// A private function for handling mouse 'hovering'
var handleHover = function(e) {
$('#debug').append('handleHover<BR>');
// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
if ( p == this ) { return false; }
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = e; //jQuery.extend({},e);
var ob = this;
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
// else e.type == "onmouseover"
$('#debug').append(e.type + ': _s = ' + ob.hoverIntent_s + '<BR>');
if (e.type == "mouseover" || e.type == "mouseenter") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX; pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).bind("mousemove",track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
// else e.type == "onmouseout"
} else {
// unbind expensive mousemove event
$(ob).unbind("mousemove",track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
}
};
// bind the function to the two event listeners
return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);
$.event.special.hoverintent = {
setup: function() {
$('#debug').append('setup event hoverintent<BR>');
$(this).hoverIntent({
over: jQuery.event.special.hoverintent.over,
out: jQuery.event.special.hoverintent.out
});
},
teardown: function() {
$('#debug').append('tear down hoverintent<BR>');
},
over: function(ev) {
$('#debug').append('handle over<BR>');
ev.type = 'hoverintent';
if (ev.type != 'hoverintent')
$('#debug').append('EV TYPE DID NOT TAKE<BR>');
//$('#debug').append(dump(ev));
jQuery.event.handle.apply(this, arguments);
},
out: function(event) {
$('#debug').append('handle out<BR>');
}
}; };