JQuery-Hover out时未触发Hover事件



我正在实现我自己的"工具提示",每次您将鼠标悬停在它上面时,它都会创建一个新的div元素,并在悬停时将其删除。下面的代码是从我使用的代码中剥离出来的,但它显示了问题:当用户慢慢地将鼠标放在$('#'+fieldName)对象上并将其移开时,这段代码非常有效,但当你在对象上移动鼠标,然后快速将其拔下时,工具提示不会被删除。有没有办法改进我的代码?

我试着实现一个系统,在这个系统中,我创建了所有的工具提示框并隐藏它们,然后在悬停时显示它们,但这也带来了同样的问题,鼠标快速离开对象,悬停没有启动。

$('#' + fieldName).hover(
    function () { /* Create new DOM element */
        /* My ajax stuff here */
        var data = 'test';
        var tooltipBox = $('<div id="' + fieldName + '_tooltip">' + data + '</div>');
        $("body").prepend(tooltipBox);
    },
    function () { /* Remove Tooltip from DOM */
        $('#' + fieldName + '_tooltip').remove();
    }
);

答案:

在Robert Koritnik和sajawikio:的帮助下

如果你需要在悬停时使用AJAX调用来制作工具提示,你可以做一个小黑客来让它工作。

var callingAjax = false;
var removeTooltip = false;
$('#tooltip').hover(
     function() {
          callingAjax = true;
          $.post(.. {
              callingAjax = false;
              /* do stuff */
              if(removeTooltip)
                   /* code to remove tooltip */
              removeTooltip = false;
          });
     },
     function() {
          if(callingAjax) 
              removeTooltip = true;
          else
              /* code to remove tooltip */
     }
);

您的代码工作正常

我已经把你的代码放在一个JSFiddle中,它可以工作,所以你一定有其他问题。我可以在链接上尽可能快地移动鼠标,但工具提示每次都会被删除。

我正在使用Chrome。你的药物是什么

注意:我在JSFiddle中的代码与您的代码之间的唯一区别是,我使用了append,而您使用了prepend。出于显而易见的原因,我改变了这一点。试着改变它,你就会明白为什么。但它是双向的。

注意2:实际上,如果将append更改为prepend,它实际上模拟了鼠标的快速移动,因为当对象被预挂起时,鼠标会悬停在链接之外。因此,移动元素以模拟相同的行为,而不是尽可能快地移动鼠标。

实际问题

问题是,在创建工具提示之前,您正在hover中执行其他操作。这是否是Ajax调用并不重要。它可以是任何异步的,这样Javascript线程就可以执行下一个函数。如果它执行的时间比你在元素上停留的时间长,那么你的鼠标输出想要删除一些还没有创建的东西(稍后会创建)。

两种可能的解决方案:

  1. 首先添加工具提示,然后执行其他内容
  2. 在悬停事件执行后延迟Ajax调用

警告

我强烈建议不要在悬停事件中执行ajax代码,因为您可能会触发大量请求。实际上,这超出了浏览器所能处理的范围。如果您必须在悬停时执行ajax请求,那么可以这样做:悬停启动并准备一个函数调用,以便在它之后立即执行,但该函数只会在尚未进行ajax调用的情况下发出ajax调用:

// variable outside of hover closures
var ajaxExecuting = false;
// code to put within your hover handler
setTimeout(function() {
    if (!ajaxExecuting)
    {
        ajaxExecuting = true;
        // do your AJAX stuff
    }
}, 0);

是的,有一个问题。让速度根本不是一个因素-不要把它留给机会,并确保当你悬停进去时,你的悬停出去激活-当你悬停出去时,悬停进去激活!万无一失的这样,你就不会像你说的那样陷入"膨胀"!换句话说,一次处理一个事件是"来回切换样式",而不是使用持久处理程序。

(请参阅操作中的示例代码-当然,如果您使用的元素更大,则效果良好)-http://jsfiddle.net/4jArC/

var fieldName = "whatever";
function b(evt) { /* Remove Tooltip from DOM */
    $('#' + fieldName + '_tooltip').remove();
    $(evt.currentTarget).one('mouseover',a);
}
function a (evt) { /* Create new DOM element */
    /* My ajax stuff here */
    var data = 'test';
    var tooltipBox = $('<div id="' + fieldName + '_tooltip">' + data + '</div>');
    $("body").prepend(tooltipBox);
    $(evt.currentTarget).one('mouseout',b);
}
$('#' + fieldName).one('mouseover', a);
​

最新更新