标准 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
不是t,但是,但是我们可以设置它的样式,使其“阻碍”#b-div
。这在 this 中有说明。 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');
}
});
自
#c-div
可能并不总是完全包含在 #b-div
中,如果添加此样式,则可以使用现有代码:
#c-div {
pointer-events: none;
}
但这将导致无法与#c-div
进行交互使用鼠标。
如果您确实需要与#c-div
互动,和它不完全在#b-div
内, 你可以使用 Element.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
)
}
);
关于javascript - 如何使用绝对定位的非后代实现 mouseleave 效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30580616/