为什么 jQuery 中 :hover 只能工作一次?

5
我一直在使用以下代码片段,在Chrome/Safari和Firefox中确定用户是否悬停在锚点上。
var isURL = $("a", obj).is(":hover");

我看到有关:hover是CSS选择器的帖子,但我无法理解的是,如果obj中有1个链接,则代码返回true,但如果有2个或更多,则会抛出javascript未识别表达式hover错误。
这是一个: hover工作的fiddle:- http://jsfiddle.net/2kyaJ/122/
相同但多个元素(不起作用):- http://jsfiddle.net/2kyaJ/121/
有人能向我解释一下吗?
顺便说一句,我看到了这个... 如何检查鼠标是否悬停在jQuery元素上?
4年后,这仍然是确定用户是否悬停在元素上的最佳且似乎是唯一的方法吗? 如果是,有人能提供一个示例吗? 编辑:我必须去寻找我需要的内容,但事实证明这个简单的方法非常有效。我目前正在一个插件中使用它,该插件使用jQuery 1.9.1,在父元素(obj)的mouseover上触发动画。希望将来有人会发现它有用。使用.length代替.size,因为从1.8版本开始.size已被弃用。
        function isMouseOver() {
            if ($('a:hover', obj).length != 0) {
                return true;
            } else {
                return false;
            }                           
        }

使用方法:

var isURL = isMouseOver();

因为要使您的逻辑起作用,所有 .sample 元素都必须同时悬停。您需要单独检查哪个元素(如果有)被悬停以实现您在此处想要的效果。 - BenM
1
@BenM,如果这是真的,那么文档就是错误的:“针对选择器、元素或 jQuery 对象检查当前匹配的元素集,并在至少有一个这些元素与给定参数匹配时返回 true。” - redbmk
好的,请检查您的控制台。Sizzle不支持包含多个元素的jQuery对象的hover事件:Uncaught Error: Syntax error, unrecognized expression: hover - BenM
如果您升级到jQuery 1.9.1,错误消息将得到改善。语法错误,无法识别的表达式:不支持的伪类:hover。这表明这是jQuery选择器中的一个限制。 - Barmar
4个回答

5

:hover没有在http://api.jquery.com/上记录 - 因此我不会相信它以任何特定的方式工作。问题似乎是当集合中有多个元素要迭代时,Sizzle被这个伪选择器搞糊涂了,尽管通过查看代码我无法确定原因。

事实上,在您的第一个示例中,它甚至能够工作似乎是一个错误:http://jsfiddle.net/2kyaJ/122/ - 它不适用于jQuery 1.9。

至于如何判断元素是否处于悬停状态 - 我不确定您需要做什么情况下才需要这样做。相反,最好在触发悬停时采取行动。您可以使用mouseovermouseenter绑定到“类似于悬停”的事件。当然,还有CSS伪选择器:hover


我正在编写一个插件,当你悬停在一个元素上时,它会向左滑动,以显示右侧隐藏的内容。当鼠标移开时,它会滑回到原始位置。如果用户悬停在链接上,我不想触发动画,但是我已经在mouseover上使用了setTimeout来等待250毫秒,在mouseout上使用了1.5秒。 - KryptoniteDove

3

尝试这个fiddle:http://jsfiddle.net/2rU4U/

setInterval(function(){
    var $sample = $(".sample");

    $sample.each(function(index) {
        if($(this).is(":hover")) {
           $(this).css("background", "yellow");
        }
        else {
           $(this).css("background", "");
        }
    });  
}, 200);

如上面的评论所提到的,这尊重了可能返回一组元素而不仅仅是单个元素的事实。当然,如果有很多元素,可能会导致相当大的开销...!


谢谢,我使用fiddle只是作为行为的举例。问题的第一部分似乎已经得到了答案“不支持的伪类”,但是否有人知道确定我是否正在悬停在一个元素上的最佳方法?还是上面的mouseover到fadeout仍然是正确的方法? - KryptoniteDove

1
关于为什么它不能按你的方法工作,我认为可能是一个错误或者它没有被记录。我不太确定。
然而,在jQuery 1.7.1、1.9和2.0.0b1中, 这里有一个例子可以运行: http://jsfiddle.net/2kyaJ/125/ 基本上,你可以查询所有悬停元素并检查是否至少有一个匹配项(使用$(".sample:hover").length而不是$(".sample").is(":hover")),而不是使用.is().
我有这样一种印象,即当任何一个.sample元素被悬停时,你想要突出显示所有.sample元素,因此第一个jsfiddle是这样的。但是,如果你只想突出显示悬停元素,你可以尝试像这样做: http://jsfiddle.net/2kyaJ/126/ 此外,如果你只是想将某些内容绑定到悬停事件上,而不是每0.2秒检查一次,你可以使用.hover()函数:http://jsfiddle.net/2kyaJ/127/

-2
说实话,设置间隔是一个糟糕的主意...
只需设置一个悬停监听器。
$('.sample').hover(function() {
    console.log($this) // $(this) is the currently hovered element
})

JSFiddle:{{link1:http://jsfiddle.net/jeffshaver/2kyaJ/124/}}


这并没有回答问题,它会将所有类为.sample的元素更改为黄色。我想确定正在悬停的元素是什么。这个fiddle只是行为的一个例子。 - KryptoniteDove
如果您想找出哪个“.sample”正在被悬停,那么只需在hover监听器内部使用$(this)即可。它仍然有效... 即 $('.sample')。hover(function(){ console.log($(this)); });返回该悬停的HTML元素。 - Jeff Shaver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接