如何用绝对定位的非后代实现鼠标离开效果
How to achieve mouseleave effect with absolutely-positioned non-descendants?
标准mouseout
事件的一个问题是,它不仅在光标离开以元素外部边界为界的屏幕区域时触发,而且当光标悬停在包含在该边界内的其他元素上时也会触发。
jQuery的mouseleave
事件的基本原理是,当光标离开元素的外部边界区域时,仅向发出信号。
不幸的是,这似乎只在"阻塞"元素是"阻塞"元素的后代时才有效。如果"阻塞"元素通过绝对定位处于其所在位置,则当鼠标悬停在其上时,"阻塞"元素上的mouseleave
事件被触发。
例如,使用以下HTML:
<div id="b-div">
<div id="d-div"><span>d</span></div>
</div>
<div id="c-div"><span>c</span></div>
…#d-div
是#b-div
的真正后代,而#c-div
不是,但是,但是我们可以对它进行样式设置,以便它"阻碍"#b-div
。这在这个 jsFiddle中有说明。
如果现在在#b-div
上定义以下事件:
$( '#b-div' ).bind( {
mouseenter: function () {
$( this ).addClass( 'outlined' );
},
mouseleave: function () {
$( this ).removeClass( 'outlined' );
}
} );
…然后将鼠标悬停在#b-div
的外周长内,会在该周长上出现一个蓝色轮廓,除非鼠标在#c-div
上。
是否有一种方法可以获得#b-div
和#c-div
与mouseleave
实现#b-div
和#d-div
相同的效果?
编辑:我已经修复了jsFiddle中显示的示例。这个示例的原始版本显示了一个不具代表性的特殊情况,在这种情况下,所有阻塞元素都与被阻塞元素重叠。在这种特殊情况下,可以通过在阻塞元素和被阻塞元素上定义相同的事件来模拟期望的效果,因此,实际上,将阻塞元素变成被阻塞元素的一小块。当阻塞元素没有完全包含在被阻塞元素的外围时(如修改后的jsFiddle所示),这将不起作用。更一般地说,任何基于在阻塞元素上使用mouseover
事件的解决方案都注定会失败,因为真正的问题是为了防止(或使无效)阻塞元素上的虚假mouseleave
。
根据您的初始帖子#c-div
完全包含在#b-div
中:
$('#b-div, #c-div').on( {
mouseenter: function (ev) {
$('#b-div').addClass('outlined');
},
mouseleave: function (ev) {
$('#b-div').removeClass('outlined');
}
});
小提琴1
由于
#c-div
可能并不总是完全包含在#b-div
中,您可以使用您现有的代码,如果您添加以下样式:
#c-div {
pointer-events: none;
}
但是这将使使用鼠标与#c-div
交互变得不可能。
小提琴2
如果你需要与#c-div
, 和交互,它不完全在#b-div
内,你可以使用元素。getBoundingClientRect如下:
$('#b-div, #c-div').on('mousemove mouseleave',
function(ev) {
var br= $('#b-div')[0].getBoundingClientRect();
$('#b-div').toggleClass(
'outlined',
ev.pageX > br.left && ev.pageX < br.left+br.width &&
ev.pageY > br.top && ev.pageY < br.top +br.height
)
}
);
小提琴3
如果你不能使用Rich对pointer-events: none
的建议(也许你需要支持IE 10或者你确实需要与绝对定位的div进行交互),你可以手动检查事件不会使用relatedTarget
进入#c-div
。
但是,您还必须检查#c-div
的mouseleave不会转到#b-div
。
$( '#b-div' ).bind( {
mouseenter: function () {
$( this ).addClass( 'outlined' );
},
mouseleave: function (e) {
if (e.relatedTarget.id == 'c-div' || $.contains(document.getElementById('c-div'), e.relatedTarget)) {
return;
}
$( this ).removeClass( 'outlined' );
}
} );
$( '#c-div' ).bind( {
mouseleave: function (e) {
if (e.relatedTarget.id == 'b-div' || $.contains(document.getElementById('b-div'), e.relatedTarget)) {
return;
}
$( '#b-div' ).removeClass( 'outlined' );
}
});
#a-div {
position: relative;
margin: 20px;
}
#b-div {
height: 100px;
width: 100px;
background-color: #555;
padding: 50px;
}
#c-div {
position: absolute;
height: 50px;
width: 200px;
top: 100px;
left: 100px;
background-color: #999;
}
#d-div {
height: 50px;
width: 50px;
background-color: #ddd;
text-align: center;
}
#c-div span {
margin: 21.5px;
line-height: 50px;
}
#d-div span {
margin: auto;
line-height: 50px;
}
.outlined {
outline: 10px solid steelblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a-div">
<div id="b-div"><div id="d-div"><span>d</span></div></div>
<div id="c-div"><span>c</span></div>
</div>
- 如何使用动画实现纸张推车
- EaseJS拖放;放下(动画CC)电影剪辑的鼠标坐标
- 客户端服务器REST API captcha实现
- 当鼠标悬停在文本中的单词上时显示警报
- JsFiddle上的鼠标事件不起作用
- 每当您在选择器内移动鼠标时,悬停功能就会重复
- 如何实现此布局
- 如何在鼠标悬停时在另一个图像上滑动图像.
- 鼠标悬停事件影响列表中所有行中的按钮,而不仅仅是特定按钮
- 如何在页面上的多个缩略图集的鼠标悬停时实现 jQuery 图像循环
- 实现滚动条,但光标根本没有移动?另外,如果可以的话,请告诉我如何在此嵌入鼠标滚动
- 高图表.js添加鼠标悬停功能或悬停状态(实现中断图表?
- jQuery试图实现鼠标方向和角度
- 如何在 js 和 css3 中使用鼠标光标单击实现滚动图像
- 尝试实现鼠标移动到这个基本的javascript代码
- 有人知道如何在jQuery/javascript中实现简单的鼠标手势吗?
- 如何在javascript中实现鼠标拖动
- 如何使用JS在鼠标按下后实现鼠标移动
- 如何用绝对定位的非后代实现鼠标离开效果
- 为HTML元素实现鼠标悬停背景颜色更改的最简单方法是什么