时髦的 jQuery mouseleave 行为

发布于 2024-08-18 09:32:25 字数 483 浏览 12 评论 0原文

我有一个类似菜单的下拉容器,通过绑定“mouseleave”事件来隐藏。

<div id="container">
<select>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
    <option>5</option>
</select>
</div>

我遇到的问题是,当我的容器的子元素包含一个 SELECT 对象时,其中 SELECT 的 OPTIONS 物理延伸到容器的边界之外。因此,将鼠标悬停在边界之外的选项上会触发“mouseleave”事件来触发并关闭我的下拉菜单。 SELECT 是容器的子级,因此在本例中我希望 mouseleave 事件能够识别这一点。

I have a menu-like drop down container that hides via binding the "mouseleave" event.

<div id="container">
<select>
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
    <option>5</option>
</select>
</div>

The problem I am having is when my container's child elements contain a SELECT object where the OPTIONS of the SELECT physically extend outside the bounds of the container. Consequently, hovering over the OPTIONS outside of the bounds trigger the "mouseleave" event to fire and close my drop down. The SELECT is a child of the container, so in this case I would expect the mouseleave event to recognize this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

握住我的手 2024-08-25 09:32:25

Blocka 解决方案的更新,因为它无法在 Firefox 中正常工作:

if ((typeof e.fromElement != 'undefined' && !e.fromElement.length) ||
    (typeof e.fromElement == 'undefined' && e.target.tagName != 'SELECT')) {
    // perform your mouseleave logic
}

An update on Blocka's solution as it doesn't work with Firefox correctly:

if ((typeof e.fromElement != 'undefined' && !e.fromElement.length) ||
    (typeof e.fromElement == 'undefined' && e.target.tagName != 'SELECT')) {
    // perform your mouseleave logic
}
等待圉鍢 2024-08-25 09:32:25

一个非常简单有效的解决方案是在执行操作之前控制鼠标指针坐标。
如果容器失去焦点而将焦点集中在“select”元素上,它会检查指针。如果指针位于容器内部,则它不会执行任何操作,但是如果这是容器元素,则会执行

 $('#div_solapa_lateral').bind("mouseenter",function(){
            $(this).animate({left:'0'},500);
        });

    $('#div_solapa_lateral').bind("mouseleave",function(e){
            if ( e.clientX>360 || e.clientY<60 || e.pageY>625 )
            $(this).animate({left:'-320'},500);
        });

clientX 和 clientY 到“position:relative;”的 操作
pageX 和 pageY 为“position:absolute;

A very simple and effective solution to this is to control the mouse pointer coordinates before performing the action.
If the container out of focus to focus on the element "select", it checks the pointer. If the pointer is inside the container, it does not perform any action, however if this is the container element action is performed

 $('#div_solapa_lateral').bind("mouseenter",function(){
            $(this).animate({left:'0'},500);
        });

    $('#div_solapa_lateral').bind("mouseleave",function(e){
            if ( e.clientX>360 || e.clientY<60 || e.pageY>625 )
            $(this).animate({left:'-320'},500);
        });

clientX and clientY to "position:relative;"
pageX and pageY to "position:absolute;"

蹲在坟头点根烟 2024-08-25 09:32:25

感谢无眼睑!实际上,我昨晚找到了这个问题的另一个答案,与您发布的内容非常相似。

.bind("mouseleave", function(e) { // ANSWER HERE!!!
    if (!e.fromElement.length) {
        _state.filterTrigger.data("open", false);
        setTimeout(function() { _toggleFilter(_state.filterTrigger); }, 2000);
    }
});

e.fromElement 对象给出 SELECT 中 OPTION 对象的计数。对于其他 HTML 标记,该对象未定义。我没有尝试过你的解决方案,但这也适用于我。

Thanks eyelidlessness! I actually found another answer to this problem last night that is very similar to what you posted.

.bind("mouseleave", function(e) { // ANSWER HERE!!!
    if (!e.fromElement.length) {
        _state.filterTrigger.data("open", false);
        setTimeout(function() { _toggleFilter(_state.filterTrigger); }, 2000);
    }
});

The e.fromElement object gives the count of OPTION objects in the SELECT. This object is undefined for other HTML tags. I haven't tried your solution but this works for me as well.

微凉徒眸意 2024-08-25 09:32:25

也许当下拉菜单展开时,您可以设置一个标志。选择项目后清除标志。当发生鼠标离开时,除非标志清除,否则不要隐藏菜单。

不过,我总是对这种程度的黑客 UI 事件感到紧张,因为很可能最终会让某些浏览器处于完全无法使用的状态。

Perhaps when the dropdown is expanded you could set a flag. Clear the flag when an item is selected. When a mouseleave occurs, don't hide the menu unless the flag is clear.

I always get nervous about hacking UI events to this degree though, since it's likely you'll end up leaving some browser somewhere in a totally unusable state.

未央 2024-08-25 09:32:25

大多数渲染器(我认为除了 Gecko 之外)都在单独的“窗口”中实现打开的 菜单的交互。您不太可能在所有主要浏览器上实现所需的效果...

编辑:...但也许如此。这对我在 Safari 和 Firefox 中有效。我现在无法在 IE 中进行测试,但请尝试一下:

var timer;
$('#container').mouseleave(function(e) {
    if($(e.target).parents('#container').length) {
        return;
    }
    timer = setTimeout(function() {
        $('#container select').blur();
    }, 50);
}).mouseenter(function(e) {
    if(timer) {
        clearTimeout(timer);
    }
});

编辑 2:实际上,当 < code><选择>“窗口”已打开。

Most renderers (all except Gecko, I think) implement opened <select> menus and their options in a separate "window", not as elements on the page. The page is, then, not necessarily aware of the user's interaction with an open <select> menu. It's very unlikely that you'll be able to achieve the desired effect across all the major browsers...

Edit: ... but maybe so. This works for me in Safari and Firefox. I can't test in IE right now, but give it a shot:

var timer;
$('#container').mouseleave(function(e) {
    if($(e.target).parents('#container').length) {
        return;
    }
    timer = setTimeout(function() {
        $('#container select').blur();
    }, 50);
}).mouseenter(function(e) {
    if(timer) {
        clearTimeout(timer);
    }
});

Edit 2: actually, Safari doesn't fire mouseleave (or mouseout) at all when the <select> "window" is open.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文