延迟jQuery悬停事件?


93

我想延迟jquery中的悬停事件。当用户将鼠标悬停在链接或标签上时,我正在从文件中读取内容。如果用户只是在屏幕上移动鼠标,我不希望立即发生此事件。有没有办法延迟事件触发?

谢谢。

示例代码:

$(function() {
    $('#container a').hover(function() {
        $('<div id="fileinfo" />').load('ReadTextFileX.aspx',
            {filename:'file.txt'},
            function() {
                $(this).appendTo('#info');
            }
         );
    },
        function() { $('#info').remove(); }
    });
});

更新: (1/14/09) 添加HoverIntent插件后,上面的代码更改为以下代码以实现它。实施非常简单。

$(function() {
    hiConfig = {
        sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)
        interval: 200, // number = milliseconds for onMouseOver polling interval
        timeout: 200, // number = milliseconds delay before onMouseOut
        over: function() {
            $('<div id="fileinfo" />').load('ReadTextFileX.aspx', {filename:'file.txt'},
                function() {
                   $(this).appendTo('#info');
                }
             );
        }, // function = onMouseOver callback (REQUIRED)
        out: function() { $('#info').remove();  } // function = onMouseOut callback (REQUIRED)
    }
    $('#container a').hoverIntent(hiConfig)
}

1
感谢您为hoverIntent提供用法
JavaKungFu 2014年

Answers:


91

将hoverIntent插件用于jquery:http ://cherne.net/brian/resources/jquery.hoverIntent.html

对于您所描述的内容来说,它绝对是完美的选择,并且我几乎在每个需要鼠标悬停激活菜单等项目中都使用了它...

这种方法有一个陷阱,例如某些接口没有“悬停”状态。手机浏览器(如iPhone上的Safari)。您可能隐藏了界面或导航的重要部分,而无法在此类设备上打开它。您可以使用特定于设备的CSS来解决此问题。


或者,这个插件也可以像一个迷人的github.com/john-terenzio/jQuery-Hover-Delay
云母

50

您需要检查悬停计时器。如果它不存在(即这是第一个悬停),则创建它。如果存在(即这不是第一次悬停),请杀死它并重新启动。将计时器有效负载设置为您的代码。

$(function() {
    var timer;

    $('#container a').hover(function() {
        if(timer) {
            clearTimeout(timer);
            timer = null
        }
        timer = setTimeout(function() {
            $('<div id="fileinfo" />').load('ReadTextFileX.aspx',
                {filename:'file.txt'},
                function() {
                    $(this).appendTo('#info');
                }
            );
        }, 500)
    },
    // mouse out
    });
});

我敢打赌jQuery有一个功能可以为您解决所有这些问题。

编辑:嗯,是的,jQuery插件可以解救


9
仍然感谢非插件解决方案!
Jrgns

4
我添加了一个clearTimeout(timer); timer = null; 在mouseout端,但是效果很好,避免了YAP(还有另一个插件)
Andiih 2012年

@Andiih非常高兴,谢谢您向我介绍“ YAP”的缩写。
2012年

您可能是说
debounce

11

完全同意hoverIntent是最好的解决方案,但是如果您碰巧是一个不幸的草皮匠,他在一个漫长而漫长的jQuery插件审批流程网站上工作,那么以下快速而又肮脏的解决方案对我来说很有效:

$('li.contracted').hover(function () {
    var expanding = $(this);
    var timer = window.setTimeout(function () {
        expanding.data('timerid', null);

            ... do stuff

    }, 300);
    //store ID of newly created timer in DOM object
    expanding.data('timerid', timer);
}, function () {
    var timerid = $(this).data('timerid');
    if (timerid != null) {
        //mouse out, didn't timeout. Kill previously started timer
        window.clearTimeout(timerid);
    }
});

如果鼠标停留超过300ms,这仅用于扩展<li>。


谢谢,发现这比其他答案更有用。

6

您可以在mouseout事件上将setTimeout()调用与clearTimeout()一起使用。


1

在2016年,Crescent Fresh的解决方案无法达到我的预期,因此我想到了:

$(selector).hover(function() {
    hovered = true;
    setTimeout(function() {
        if(hovered) {
            //do stuff
        }
    }, 300); //you can pass references as 3rd, 4th etc. arguments after the delay

}, function() {
    hovered = false;
});

-2

我的解决方案很简单。如果用户在obj上保持mouseenter超过300ms,则延迟打开菜单:

var sleep = 0;
$('#category li').mouseenter(function() {
    sleep = 1;
    $('#category li').mouseleave(function() {
        sleep = 0;
    });
    var ob = $(this);
    setTimeout(function() {                         
        if(sleep) {
            // [...] Example:
            $('#'+ob.attr('rel')).show();
        }
    }, 300);
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.