jQuery有没有适用于.delegate('hover')的handleout?

38

我正在尝试使用:

$('mydiv').delegate('hover', function() {  
    $('seconddiv').show();  
}, function() {  
    //For some reason jQuery won't run this line of code  
    $('seconddiv').hide();  
});

如果您提供您的HTML示例,我可以根据您的标记提供更具体的答案。 - user113716
5个回答

50

jQuery 1.9+ 不再支持伪事件hover,因此 User113716 的好答案将不再奏效(升级指南)。

另外自从jQuery 3.0 正式弃用了delegate()绑定事件,因此请使用新的on()(文档)进行所有事件绑定。

您可以通过将hover替换为mouseenter mouseleave并切换到on()语法来轻松迁移User113716的解决方案:

$('mydiv').on('mouseenter mouseleave', 'seconddiv', function(event) {
    $(this).toggle( event.type === 'mouseenter' );  
});
如果你的问题比简单的 "toggle" 更复杂,我建议绑定两个单独的事件:
$('mydiv').on('mouseenter', 'seconddiv', function( event ) {
    // do something
}).on('mouseleave', 'seconddiv', function( event ) {
    // do something different
});

NB:自从v1.9中删除了hover并在v1.7中引入了on(),因此没有必要使用delegate()来解决问题。但如果出于某种原因您喜欢它,它仍然存在(目前)。

$('mydiv').delegate('seconddiv','mouseenter mouseleave', function(event) {
    $(this).toggle( event.type === 'mouseenter' );  
});

2
我不知道你可以使用 on 绑定两个事件。 - Chris Abrams
1
delegate()在3.0中已被弃用 https://jquery.com/upgrade-guide/3.0/#breaking-change-on-quot-ready-quot-fn-removed - Callat

44
使用 delegate()(文档),你可以将其分配给一个容器元素,并将第一个参数设置为应该触发事件的元素。

此外,.delegate() 只接受一个函数作为参数,因此对于 hover 事件,你需要测试 event.type 来确定是使用 show()(文档) 还是使用 hide()(文档)

$('.someContainer').delegate('.someTarget','hover', function( event ) {
    if( event.type === 'mouseenter' )  
        $('seconddiv').show();  
    else
        $('seconddiv').hide();  
});

实现显示/隐藏,更短的写法是使用 toggle()(文档),它可以接受一个 switch 参数,其中 true 表示 showfalse 表示 hide

$('.someContainer').delegate('.someTarget','hover', function( event ) {
    $('seconddiv').toggle( event.type === 'mouseenter' );  
});
注意,`mouseenter`事件在`jQuery1.4.3`以上版本中才被支持。如果你正在使用`1.4.2`,则会作为`mouseover`事件进行报告。
$('mydiv').delegate('seconddiv','hover', function( event ) {
    $(this).toggle( event.type === 'mouseenter' );  
});

@Chris:你的意思是当你悬停在 mydiv 上时,你想要它嵌套的 seconddiv 显示出来,然后当你离开 mydiv 时隐藏吗?mydiv 元素是页面加载时的一部分吗?还是稍后添加的? - user113716
seconddiv嵌套在第一个div中。有时候mydiv在页面加载时就存在,有时候它是在DOM加载后添加的。 - Chris Abrams
@Chris:我想我明白了。我会更新,你可以告诉我是否符合你的意思。 - user113716
这个解决方案在所有主流浏览器中,使用jQuery 1.9.1后停止工作。一个解决方法是绑定mouseentermouseleave事件: $('mydiv').delegate('seconddiv','mouseenter mouseleave', ...。我找不到任何关于新版jQuery是bug还是feature的信息,所以在jQuery跟踪器上报了一个bug:http://bugs.jquery.com/ticket/13470。 - DerVO
这不是一个错误,而是一个特性。所以你不能再委托给hover了。由于某些原因,我的编辑被拒绝了,所以我添加了一个答案。 - DerVO
显示剩余3条评论

2
我知道原帖想要一个“委托”解决方案(当我遇到这个问题时,我也是这样想的...)
但是经过进一步的调查,我发现完全可以在不用任何js/jquery代码的情况下实现相同的效果
你所需要的只是一点CSS
.someContainer .seconddiv{
    display : none;
}

.someContainer:hover .seconddiv{
    display : block;
}

在MO中,这是一种更高效/轻量级的解决方案。


这是使用CSS的一种不错的方法 - 当我遇到这个问题时,我需要在鼠标进入后触发另一个JS事件。 - Chris Abrams
如果您需要在触摸屏设备上与.seconddiv中的某些内容进行交互,请注意...事件的顺序将首先触发悬停,然后是对.seconddiv的点击。 - parker.sikand

1

.delegate() 没有 handle out。此外,您需要使用第一个参数指定要定位的元素。

您可以尝试类似于以下内容的代码:

$('table').delegate('tr', 'hover', function() {  
    $(this).toggle();
});

1

编辑:已删除错误信息。

如果您想使用hover()方法而不需要委托,可以使用以下代码:

$('#mydiv').hover(function() {  
    $('#seconddiv').show();  
}, function() {  
    $('#seconddiv').hide();  
});

其次,delegate 是将事件处理程序分配给子元素,因此您需要首先指定选择器。如果您需要确保此事件处理程序存在于动态添加的元素中,则在这种情况下我更喜欢使用 .live()mouseentermouseleave
$('#mydiv').live('mouseenter', function() {  
    $('#seconddiv').show();  
}).live('mouseleave', function() {  
    $('#seconddiv').hide();  
});

jQuery接受hover作为bindlivedelegate的事件类型。它映射到mouseenter/mouseleave - user113716
那是不正确的。hover是一种事件类型。它甚至在jQuery文档中作为delegate的示例之一。http://api.jquery.com/delegate/ - Michael Irigoyen
谢谢。它在.bind方法的API文档中没有显示,所以我没有意识到。 - mVChr
我对 bind 的理解错了。它只适用于 livedelegate - user113716
第二个 div 嵌套在第一个 div 中,如果你将鼠标悬停在第二个 div 上,它将消失。 - Chris Abrams

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