I'm trying to implement my own tooltip plugin with an optional delayed hiding on mouseout event. This wouldn't be a problem if the tooltip wasn't displaying so frequently a need it to. I want to use it in a chat room where messages are starting with users' nicks which are links and on mouseover event the tooltip should display. It looks like this:
nick: some message othernick: some other message nicknick: some nicknick's message ... on `mouseovering` the 'nick' link, the tooltip displays and on mouseout it delays a certain time and then hides itself. everything's ok so far. The problem appears in the moment when I quickly switch between two links (I'm over 'nick' and will roll the mouse quickly over 'othernick'). The timeout delaying the tooltip hiding didn't run out yet, I'm over other link and I want the timeout to be cleared to not to hide the tooltip which should remain displayed. Below is a fragment of my plugin's code. It contains only relevant code, to show transparently the situation (it uses dimensions plugin: http://plugins.jquery.com/project/dimensions). This is my first jQuery plugin, but technically I think this is how it should work (and the problem is probably in clearing the timeout, not in plugin structure). So if you got any ideas, post it please. Thank you guys. Here is the code: (function($) { var $straytip, $straytipInner; var hideTimerId = 0; var isActive = false; // plugin $.fn.straytip = function(options) { //setting main options var opts = $.extend({}, $.fn.straytip.defaults, options); //iterating all matched elements return this.each(function() { $this = $(this); //if there are any specific options set it var o = $.meta ? $.extend({}, opts, $this.data()) : opts; //creation of tooltips div if (!$("#straytip").length){ $straytipInner = $('<div id="straytipInner"></div>'); $straytip = $('<div id="straytip"></div>') .css({zIndex: o.zIndex, position: "absolute"}) [insertionMethod](insertionElement)//specified in setup .hide(); } //processing the hover effect $this.hover( function(){$.fn.straytip.over($(this), o)}, function(){$.fn.straytip.out($(this), o)} ); }); }; $.fn.straytip.over = function($this, opts) { if (hideTimerId > 0){//HERE IS WHERE IT SHOULD CLEAR THE TIMEOUT WHICH DELAYS HIDING $straytip.hide(); isActive = false; clearTimeout(hideTimerId); hideTimerId = 0; } var offset = $this.offset(); var height = $this.height(); var width = $this.width(); $straytip.css({top: offset.top + height + opts.topOffset, left: offset.left + width + opts.leftOffset}); $straytip.show(); isActive = true; }; $.fn.straytip.out = function($this, opts) { if (opts.delayHide > 0){//delayed hiding hideTimerId = setTimeout( function(){ $straytip.hide(); isActive = false; hideTimerId = 0; }, opts.delayHide ); } else { $straytip.hide(); isActive = false; } }; $.fn.straytip.defaults = { topOffset: 15, leftOffset: 15, delayHide: 0, zIndex: 100 }; //setup var insertionMethod = 'prependTo', insertionElement = 'body'; $.straytip = {}; $.straytip.setup = function(options) { if (options && options.insertionMethod && (options.insertionMethod).match(/appendTo|prependTo|insertBefore| insertAfter/)) { insertionMethod = options.insertionMethod; } if (options && options.insertionElement) { insertionElement = options.insertionElement; } }; })(jQuery);