Focusout 被触发两次

use*_*169 4 jquery jquery-ui jquery-ui-dialog

我有一个文本框和一个 Jquery UI 对话框。当用户在文本框中输入完成并按 Enter 键后,我想显示该对话框。为了实现这一点,我使用以下代码:

$(document).ready(function () {
    var helpDial = $('#helpDialog');
    var input = $('#helpSearch');

    helpDial.dialog({
        width: 800,
        autoOpen: false,
        modal: true,
        title: "Templates",
        position: [165, 158]
    });

    input.focusin(function () {
        helpDial.dialog('close');
    }).focusout(function () {
        helpDial.dialog('open');
    }).on('keypress', function (e) {
        var code = (e.keyCode ? e.keyCode : e.which);
        if (code == 13) {
            input.focusout();
            return false;
        }
    });
});

<input id="helpSearch" />
<div id="helpDialog"></div>
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/7Fpm4/1

问题是,当我按下 Enter 键时, 会focusout被调用两次,一次input.focusout()helpDial.dialog('open')focusout事件处理程序中,另一次是在之后。这会导致创建两个背景叠加,当我关闭对话框时,一个叠加仍然可见。

我究竟做错了什么?有没有更好的方法来处理这种情况——“在文本字段中按下回车键会打开一个 jQuery 对话框”。谢谢。

sal*_*uce 6

阻止事件触发的唯一方法是取消绑定事件处理程序。或者,根据情况,根据事件触发时可用的信息采取不同的行动。

focusout每当元素失去焦点时都会触发该事件。在这种情况下,每次用户点击文本框时,focusin都会触发一个事件。一旦光标离开文本框(在打开对话框时发生),focusout就会触发该事件。

你代码的问题是你强行调用了focusout事件,然后在focusout打开对话框的时候自然会调用事件。因此,更改您的代码如下:

$(document).ready(function () {
    var helpDial = $('#helpDialog');
    var input = $('#helpSearch');

    helpDial.dialog({
        width: 800,
        autoOpen: false,
        modal: true,
        title: "Templates",
        position: [165, 158]
    });

    input.on('focusin', function () {
        input.on("focusout", textboxFocusOut);
    }).on('keypress', function (e) {
        var code = (e.keyCode ? e.keyCode : e.which);
        if (code == 13) {
            textboxFocusOut();
        }
    });

    function textboxFocusOut() {
        input.off("focusout", textboxFocusOut);
        helpDial.dialog('open');                
    }

});
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/8L7EL/1/

这段代码正在做的是一个功能结合到focusout 了内 focusin 处理。如果用户离开文本框,focusout将调用事件处理程序,立即解除focusout事件绑定(以防止多次绑定函数)。如果用户按下回车键,则会手动调用该函数,这会focusout在打开对话框之前移除事件处理程序,以防止focusout在对话框打开时自动触发事件。