【问题标题】:Jquery - techniques for extending 'perimeter' for mouseout?Jquery - 扩展鼠标悬停“周长”的技术?
【发布时间】:2011-09-06 07:55:36
【问题描述】:

我想实现这样的行为,即当鼠标指针悬停在某个 div 上时触发 mouseover/hover 事件,但是当鼠标指针离开 div 时不会触发 mouseout 事件,而是在离开区域 10px 时触发在 div 这边。

有什么方法可以在不涉及创建更大的父 div 以将 mouseout 事件绑定到的情况下实现这一点?

【问题讨论】:

  • 那么mouseout和mouseover的区域不一样?
  • 听起来你必须实现自己的悬停版本,通过跟踪鼠标位置并检查它相对于 div 的位置。
  • 我不知道是否有直接的方法可以做到这一点,但可能会在 mouseover 事件上创建一个包装 div 并在 mouseout 时将其删除。 jquery 有一个 .wrap/.unwrap 函数。那么显然包装器 div 会有一个填充或其他东西。您可以在包装器 div 上为 mouseout 事件创建一个委托事件,它应该以这种方式触发。
  • @Matt - 有趣,没想到。

标签: javascript jquery


【解决方案1】:

我的评论让我感兴趣,看看这是否可行,而且实际上很容易。不知道它在不同的浏览器和大量 div 中运行得有多好,但在这个例子中它可以工作:

http://jsbin.com/exulef/2/edit

var hello = $('#hello');
var position = hello.offset();
var height = hello.height();
var width = hello.width();

$(document).mousemove(function(e) {
  if (hello.data('inside')) {
    if ((e.pageX < position.left - 10 || e.pageX > position.left + width + 10) || 
       (e.pageY < position.top - 10 || e.pageY > position.top + height + 10)) {
      hello.text(position.top + " : " + position.left + " : " + e.pageX + " : " + e.pageY + "  Outside")
        .data('inside', false);
    }
  }
  else {
    if ((e.pageX > position.left && e.pageX < position.left + width) && 
        (e.pageY > position.top && e.pageY < position.top + height)) {
      hello.text(position.top + " : " + position.left + " : " + e.pageX + " : " + e.pageY + "  Inside")
        .data('inside', true);
    }
  }  
});

hello 只是一个方形 div。很容易变成一个插件,我以后可能会做,哈哈。

编辑 - 最后我确实把它做成了一个插件:http://jmonkee.net/wordpress/2011/09/07/jquery-extended-hover-plugin/

【讨论】:

  • 不错的插件,尝试使用它,想知道如何将mouseOutExtend的参数传递到半径外100像素?
  • @Chamilyan 您将它作为第三个参数传递给插件:$('#hover').hoverExtend(mouseOverFunction, mouseOutFunction, { mouseOutExtend: 100 }); - jsfiddle.net/qeRQv/2
【解决方案2】:

有一种方法可以在没有外部 div 的情况下做到这一点,但这意味着即使没有悬停,您的 div 也会有边距。

它利用了padding在div里面,margin在外面的事实。

  • 当什么都没有发生时,我们有一个margin,我们必须进入div内部才能悬停。

  • 当它悬停时,边距变为填充,这样当鼠标离开 div 时,我们在 div 内的时间会多一点。

  • 当我们离开填充时,它又回到了边距。

css 类似于:

.a{
   margin:10px;
}
div.b{
   padding:10px;
   margin:0;
}

请注意,重要的是要有一个更具体的 b 选择器,以便在不使用重要且不注意顺序的情况下应用它。

js 将是:

$(".a").bind("mouseenter",function(){
    $(this).addClass("b");
}).bind("mouseleave",function(){
    $(this).removeClass("b");
});

此处示例:http://jsfiddle.net/ynecV/

【讨论】:

  • 第二个选择器已经“更具体一点”,因为它在第一个选择器之后。无需“人为”使其更具体。
  • 我知道顺序很重要,但我(而且我知道这是一个品味问题)发现人工指定比依赖顺序更好。
【解决方案3】:

嗯,我会将所需的 div 包装在另一个 div 中并在其上绑定 mouseout - 这将是最可靠的解决方案。

但是,如果您坚持不创建另一个 div,那么我将绑定自定义 mousemove 处理程序,该处理程序将在 div 上的 mouseenter 上绑定(在文档上),并且会检测到鼠标从 div 边界框移开超过10像素。如果是这样,mousemove 处理程序将触发自定义 jQuery 事件,然后它会自行解除绑定。

【讨论】:

    最近更新 更多