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);

Reply via email to