简体   繁体   中英

jQuery Ajax mouseover event firing after mouseout

I'm creating a tooltip using jQuery that gets the tooltip contents via Ajax request and then stores it in a variable so Ajax isn't constantly fired off every time they mouseover. It all works perfectly except if you quickly swipe your mouse across a node and out it will load the tooltip and display it rather than hide it as defined in the mouseout.

Order of events expected: 1. Mouse over 2. Ajax loads content and places it in hidden tooltip div 3. Tooltip is adjusted to the corner of the node and shown 4. Mouse out 5. Tooltip is hidden from view

Order of events seen in the scenario above: 1. Mouse over 2. Mouse out quickly 3. Tooltip is hidden from view 4. Ajax loads content and tooltip is shown in a fixed position until you mouse over again to get rid of it.

Here's the applicable code, there's obviously a bigger object that this is written in but I think you'll get the gist.

//Cancel code snippet
$('.tt').html();
$('.tt').hide();

//Tooltip init code snippet
$.ajax({
    type: "GET",
    url: "/tooltip/" + Tooltip.slug,
    dataType: "json",
    global: false,
    success: function(data) {
        $('.tt').html(data.description);
        Tooltip.init();
        $('.tt').attr("style","left:"+Tooltip.settings.left_offset+"px;top:"+Tooltip.settings.top_offset+"px");
        Tooltip.cache[slug] = data;
        $('.tt').show();
    }
});

The hoverIntent plug-in allows you to avoid accidental mouseovers.

Add code to see if the mouseout has fired. If it did, than do not run the show() portion.

Not sure why you need tool-tip from server. You can use jQuery Tooltip to achieve same stuff Demo Page

Hope this help

我认为您应该检查成功句柄,看看是否应该在鼠标移出时显示工具提示。

That's happening because the ajax request is not finished yet when the mouse has already left the node. It will just do its thing, wait for a response from the server, and then show the tooltip as defined in your success function.

One way to combat this would be to have an variable, say isHovering , which contains the node that is currently being hovered over. You could use the node's id for this: add it to the var immediately upon hover (before firing the ajax function), and set the var back to false upon mouseout.

Then, in your ajax function, before rendering anything, check the var and only render if it contains the correct id.

Off the top of my head (not tested):

var isHovering = false;
$('.node').mouseover(function() {
      isHovering = $(this).attr('id');
}).mouseout(function() {
      isHovering = isHovering == $(this).attr('id') ? false : isHovering; //don't change if mouse on different node
});

and then in your ajax() function:

//Tooltip init code snippet
$.ajax({
    type: "GET",
    url: "/tooltip/" + Tooltip.slug,
    dataType: "json",
    global: false,
    success: function(data) {
        if(isHovering == $(this).attr('id')) {
           $('.tt').html(data.description);
           Tooltip.init();
           $('.tt').attr("style","left:"+Tooltip.settings.left_offset+"px;top:"+Tooltip.settings.top_offset+"px");
           $('.tt').show();
        }

        Tooltip.cache[slug] = data; //still cache it
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM