将事件添加到创建的元素

时间:2013-04-15 14:56:14

标签: jquery

我正在更新我的代码...大多数事情都解决了。问题仍然存在:

当我在元素(1和2)之间移动鼠标时,工具提示不会显示。

我认为这是因为我在元素鼠标停留方面有延迟:

$this.mouseleave(function (e) {
  tooltip.timer = setTimeout(function () {
    $("." + options.class).detach();
  }, !options.mouse || options.static ? options.delay || 0 : 0);
}), // Mouse leave  

我有它允许鼠标移动到工具提示中,当它有链接时。

当鼠标移过另一个元素时,想法是取消隐藏延迟。

可以在http://jsfiddle.net/mdmoura/RPUX6/

中测试该插件

整个代码如下:

(function ($) {

  $.fn.Tooltip = function (options) {

    var defaults = {
      class: 'Tooltip',
      content: '',      
      delay: 120,
      mouse: false,
      offset: [0, -20],
      static: true,
      effect: function ($element, $tooltip) {
        $tooltip.fadeIn(200);
      }      
    };

    options = $.extend({}, defaults, options);

    $(this).each(function (e) {
      var $this = $(this);
      var tooltip = { timer: null, title: $this.attr('title') };

      $this.mouseenter(function (e) {

        var $tooltip =
          $("<div>")
          .attr("class", options.class)
          .html(options.content !== '' ? (typeof options.content === 'string' ? options.content : options.content($this, $tooltip)) : tooltip.title)
          .appendTo('body');

        $this.attr('title', '');

        var position = [0, 0];

        if (options.mouse) {
          position = [e.clientX + options.offset[0] + $(window).scrollLeft(), e.clientY + options.offset[1] + $(window).scrollTop()];
        } else {
          var coordinates = $this[0].getBoundingClientRect();       
          position = [
            (function () {
              if (options.offset[0] < 0)
                return coordinates.left - Math.abs(options.offset[0]) - $tooltip.outerWidth() + $(window).scrollLeft();
              else if (options.offset[0] === 0)
                return coordinates.left - (($tooltip.outerWidth() - $this.outerWidth()) / 2) + $(window).scrollLeft();
              else
                return coordinates.left + $this.outerWidth() + options.offset[0] + $(window).scrollLeft();

            })(),
            (function () {
              if (options.offset[1] < 0)
                return coordinates.top - Math.abs(options.offset[1]) - $tooltip.outerHeight() + $(window).scrollTop();
              else if (options.offset[1] === 0)
                return coordinates.top - (($tooltip.outerHeight() - $this.outerHeight()) / 2) + $(window).scrollTop();
              else
                return coordinates.top + $this.outerHeight() + options.offset[1] + $(window).scrollTop();

            })()
          ];
        }

        $tooltip.css({ left: position[0] + 'px', top: position[1] + 'px' });

        options.effect($this, $tooltip.stop(true, true));

        $tooltip.mouseenter(function () {
          window.clearTimeout(tooltip.timer);
          tooltip.timer = null;
        }); // Tooltip enter

        $tooltip.mouseleave(function () {
          tooltip.timer = setTimeout(function () {
            $tooltip.remove();
          }, !options.mouse || options.static ? options.delay || 0 : 0);
        });

      }), // Mouse enter

      $this.mouseleave(function (e) {
        tooltip.timer = setTimeout(function () {
          $("." + options.class).remove();
        }, !options.mouse || options.static ? options.delay || 0 : 0);
      }), // Mouse leave  

      $this.mousemove(function (e) {
        if (options.mouse && !options.static) {
          $("." + options.class).css({ left: e.clientX + options.offset[0] + $(window).scrollLeft() + 'px', top: e.clientY + options.offset[1] + $(window).scrollTop() + 'px' });
        }
      }); // Mouse move
    }); // Each
  }; // Tooltip
})(jQuery); // JQuery

我正在使用超时来允许鼠标在工具提示上移动。

有谁知道如何解决当前的问题?

谢谢!

7 个答案:

答案 0 :(得分:2)

您可能想尝试此插件 - jQuery Powertip

您可以使用mouseOnToPopup选项与工具提示进行互动。

$('#mouseon-examples div').powerTip({
    placement: 'e',
    mouseOnToPopup: true // <-- Important bit
});

“您还可以在官方jsFiddle demo

上使用PowerTip

答案 1 :(得分:0)

用以下内容替换你的mouseleave功能:

    $(this).mouseout(function (e) {
       setTimeout(function(){
       $("#Tooltip").remove();
       }, 1000);
    }),

但是在1s之后,问题将是相同的:工具提示将消失。

答案 2 :(得分:0)

创建工具提示后:

    $('#Tooltip').mouseenter(function(){
      $(this).addClass('active');
    });
     $('#Tooltip').mouseleave(function(){
        setTimeout(function(){
          $("#Tooltip").remove();
        }, 1000);  
    });   

当您离开工具提示区域时,请检查“活动”类是否存在。

  $(this).mouseout(function (e) {
    if($('#Tooltip').hasClass('active'))
    {
      setTimeout(function(){
        $("#Tooltip").remove();
      }, 1000);
    }
  });

答案 3 :(得分:0)

  $this.mouseleave(function (e) {
    setTimeout(function(){ ...

也许你忘记了帖子中的一些代码,但是超时的id不会存储在任何地方,因此无法清除。您可以编写timer = setTimeout(...,其中计时器定义如下

 $(this).each(function () {     
   var $this = $(this),
       timer;

然后你可以轻松清除

 $tooltip.mouseenter(function (e) {
   clearTimeout(timer);
 });

你的mouseleave处理程序应该是

 $tooltip.mouseleave(function (e) {
  $(this).remove(); //or $tooltip.remove();
 })  

答案 4 :(得分:0)

http://jsfiddle.net/RPUX6/76/

 $this.mouseleave(function (e) {
      $("." + options.class).fadeOut(500, function() {
          this.remove();
      });
 }), // Mouse leave 

我确认这确实删除了工具提示。我不确定你为什么说它没有。奇怪。

答案 5 :(得分:0)

正如我所说,我支持apaul34208建议“使用已经存在的插件,人们已经遇到并考虑过角落案例”。也许这个特定的插件不行,但考虑到工具提示插件的数量,你应该找到你的需要。

话虽如此:

您的问题是,当您应该执行类似.remove()的操作时,您的功能会系统地调用check if I should remove the tooltip, if yes do so

function incrVisCounter($tooltip){
    var cnt = 1 + $tootltip.data('visCounter');
    $tootltip.data('visCounter', cnt);
}

function decrVisCounter($tooltip){
    setTimeout(function(){
        var cnt = $tootltip.data('visCounter') - 1;
        $tootltip.data('visCounter', cnt);
        if (cnt <= 0) {
            $tooltip.remove();
        }
    }, 300);
}


    $this.mouseenter(function (e) {
        displayTooltipIfNotShownAlready($this); //<- you will need to write some code here ...

        incrVisCounter( $('#tooltip') );
    });

    $this.mouseleave(function (e) {
        decrVisCounter( $('#tooltip') );
    });


    $tooltip.mouseenter(function (e) {
        incrVisCounter( $(this) );
    });

    $tooltip.mouseleave(function (e) {
        decrVisCounter( $(this) );
    });

$('.'+options.class).remove()会删除您网页上的任何工具提示。您必须仅定位特定的一个。

一个建议:

[edit]不要忘记var关键字...

 $this.mouseenter(function(){
     var $tooltip = ...

     $this.data('tooltip', $tooltip);
 });

 $this.mouseleave(function(){
     var $tooltip = $this.data('tooltip');
     setTimeout(function(){ $tooltip.remove() }, delay);
 });

答案 6 :(得分:0)

你想做什么。

在要触发工具提示的区域上侦听鼠标悬停/单击事件。 那部分你做了。

在工具提示show上绑定一个全局事件监听器。听取mousemove,然后检查你是否在工具提示或触发元素内。

如果您不是,则隐藏工具提示并删除全局偶数监听器。

一些伪代码

onShow: function(){
  $('body').off('mousemove');
  //might want to do _.debounce to make sure you dont trigger it to often
  $('body').on('mousemove', function(e){
     if(!$tooltip.has(e.target) && !$this.has(e.target)) {
       $tooltip.hide(); 
     }
  });
}

onHide: function(){
  //naturally you should be more careful with this 
  //and not just blindly remove all mousemose on the body
  //easy fixed by giving the event a unique id
  $('body').off('mousemove')
}