4

テキストボックスとJqueryUIダイアログがあります。ユーザーがテキストボックスへの入力を完了して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>

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

問題は、Enterキーを押すと、focusoutが2回呼び出されることです。1回目はイベントハンドラーinput.focusout()のの直後から2回目です。これにより、2つの背景オーバーレイが作成され、ダイアログを閉じても1つのオーバーレイが表示されたままになります。helpDial.dialog('open')focusout

私は何が間違っているのですか?このシナリオを処理するためのより良い方法はありますか?'テキストフィールドでEnterキーを押すと、jQueryダイアログが開きます'。ありがとう。

4

3 に答える 3

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');                
    }

});

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

このコードが実行しているのは、ハンドラーfocusout 内に 関数をバインドすることです。ユーザーがテキストボックスから移動すると、イベントハンドラーが呼び出され、イベントがすぐにバインド解除されます(関数が複数回バインドされないようにするため)。ユーザーがEnterキーを押すと、関数が手動で呼び出され、ダイアログを開く前にイベントハンドラーが削除され、ダイアログが開いたときにイベントが自動的にトリガーされないようにします。focusin focusoutfocusoutfocusoutfocusout

于 2012-07-30T01:05:17.413 に答える
3

最も明白な解決策は、関数enter_pressedに通知するような変数を使用することです。focusout

$(function () {
    var helpDial = $('#helpDialog'),
        input = $('#helpSearch'),
        enter_pressed = false;

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

    input.on('focusout', function () {
        if( !enter_pressed ) {
            helpDial.dialog('open');
        } else {
            enter_pressed = false;
        }
    }).on('keypress', function (e) {
        var code = (e.keyCode ? e.keyCode : e.which);
        if (code == 13) {
            enter_pressed = true;
            helpDial.dialog('open');
        }
    });
});

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

しかし、もっとクリーンな解決策があると思います。やってみて思いつきます。

余談
ですが、.focusinイベントハンドラーは本当に必要ですか?

于 2012-07-30T00:05:40.270 に答える
0

http://jsfiddle.net/7Fpm4/2/例を更新しました。input.focusin(function()をinput.change(function())に変更しました。

于 2012-07-29T23:45:42.907 に答える