Set behavior with setTimeout and clearTimeout?

Set behavior with setTimeout and clearTimeout?

Hello,

I created a JQuery tooltip plugin but I have a problem.

I need to be able to move the mouse over the tooltip ...

I tried to make this work with setTimeout and clearTimeout but no luck.

I have a working version here: http://www.codepen.io/mdmoura/pen/KdyJH

The important code is at the end of Mouse Enter event and in Mouse Leave event.

Here is the plugin code (I added comments in uppercase to explain what I am trying to do):

  1. // JQuery
  2. (function ($) {
  3.   // Tooltip
  4.   $.fn.Tooltip = function (options) {
  5.     var defaults = {         
  6.       class: 'Tooltip',
  7.       content: '',
  8.       delay: [200, 200],
  9.       cursor: false,
  10.       offset: [0, 1],
  11.       hide: function ($element, $tooltip) {
  12.         $tooltip.fadeOut(200);
  13.       },
  14.       show: function ($element, $tooltip) {
  15.         $tooltip.fadeIn(200);
  16.       }
  17.     };
  18.     var options = $.extend({}, defaults, options);
  19.     var identity = "Tooltip_" + Math.floor(Math.random() * (9999 - 2000 + 1) + 2000);
  20.     var info = { ready: false, shown: false, timer: null, title: '' };
  21.     $(this).each(function (e) {    
  22.       var $this = $(this);
  23.       info.title = $this.attr('title') || '';
  24.       // Mouse enter          
  25.       $this.mouseenter(function (e) {                 
  26.         if (info.ready) {
  27.           var $tooltip = $("#" + identity);
  28.         } else {
  29.           var $tooltip = $("<div>").attr("id", identity).attr("class", options.class).appendTo('body');
  30.           $tooltip.html(options.content != '' ? (typeof options.content == 'string' ? options.content : options.content($this, $tooltip)) : this.title);
  31.           info.ready = true;
  32.           $this.attr('title', '');
  33.         }
  34.         if (options.cursor) {
  35.           var position = [e.clientX + options.offset[0], e.clientY + options.offset[1]];
  36.         } else {
  37.           var coordinates = $this[0].getBoundingClientRect();
  38.           var position = [
  39.             (function () {
  40.               if (options.offset[0] < 0)
  41.                 return coordinates.left - Math.abs(options.offset[0]) - $tooltip.outerWidth();
  42.               else if (options.offset[0] === 0)
  43.                 return coordinates.left - (($tooltip.outerWidth() - $this.outerWidth()) / 2);
  44.               else
  45.                 return coordinates.left + $this.outerWidth() + options.offset[0];
  46.             })(),
  47.             (function () {
  48.               if (options.offset[1] < 0)
  49.                 return coordinates.top - Math.abs(options.offset[1]) - $tooltip.outerHeight();
  50.               else if (options.offset[1] === 0)
  51.                 return coordinates.top - (($tooltip.outerHeight() - $this.outerHeight()) / 2);
  52.               else
  53.                 return coordinates.top + $this.outerHeight() + options.offset[1];
  54.             })()
  55.           ];
  56.         }
  57.         $tooltip.css({ left: position[0] + 'px', top: position[1] + 'px' });
  58.         // HERE THE TOOLTIP IS DISPLAYED
  59.         timer = window.setTimeout(function () {
  60.           options.show($this, $tooltip.stop(true, true));
  61.         }, options.delay[0] || 0);
  62.         // THIS IS THE EVEN WHEN THE MOUSE MOVES OVER THE TOOLTIP.
  63.         // IT SHOULD CANCEL THE HIDE CALL OF THE TOOLTIP.
  64.         // AFTER THE MOUSE MOVES AWAY FROM THE "A" TAG THERE SHOULD BE A DELAY.
  65.         // THE DELAY WOULD ALLOW THE MOUSE TO MOVE TO THE TOOLTIP.
  66.         // IN THAT CASE THE HIDE CALL SHOULD BE CANCELED.
  67.         $("#" + identity).mouseenter(function() {
  68.           window.clearTimeout(timer);
  69.           timer = null;
  70.         });
  71.         // HERE THE TOOLTIP GETS HIDDEN WHEN THE MOUSE MOVES AWAY FROM IT
  72.         $("#" + identity).mouseleave(function () {
  73.           timer = setTimeout(function () {
  74.             options.hide($this, $tooltip);
  75.           }, options.delay[1]);
  76.         });
  77.       }), // Mouse enter
  78.       // HERE THE TOOLTIP GETS HIDDEN WHEN THE MOUSE MOVES AWAY FROM THE "A" TAG
  79.       // WHEN THE MOUSE MOVES OVER THE TOOLTIP THIS SHOULD BE CANCELED.
  80.       $this.mouseleave(function (e) {
  81.         window.clearTimeout(timer);
  82.         timer = null;
  83.         options.hide($this, $("#" + identity).stop(true, true));
  84.       }) // Mouse leave              
  85.     }); // Each
  86.   }; // Tooltip
  87. })(jQuery); // JQuery

Remember that I have the working example in: http://www.codepen.io/mdmoura/pen/KdyJH

Thank You,
Miguel