1

jQuery UI ダイアログがあるプログラムがあります。ユーザーが問題のダイアログの外のどこかをクリックするなど、フォーカスを失ったときにこれらのダイアログが閉じられることを望みます。

一見、これは単純な問題のように見えますが、blurイベントはまったく機能しませんでした。その後、 と にfocusin進みfocusoutましたが、奇妙な問題に遭遇しました。

ダイアログがあり、ダイアログを含む要素 (呼び出した要素の親) にアタッチfocusinした場合。ダイアログが表示された後の最初のクリックは、クリックの場所に関係なく、常にイベントを生成します。focusoutdialogfocusout

したがって、でダイアログを破棄したい場合focusout、ダイアログは破棄されるべきではないときに破棄されます。これが私の問題を示すjsFiddleです。

最初の を無視するためにいくつかのトリックを使用できることはfocusoutわかっていますが、これを正しく機能させる方法があるかどうかを知りたいです。つまり、ユーザーが最初のダイアログの外側をクリックしたときに唯一のイベントが生成されます。時間。

アップデート:

の助けを借りて、私の質問に対する納得のいく答えを見つけましたunderscore.js

私は自分の問題を部品に分解しました:

  1. 最初のfocusoutクリックで発生
  2. クリックがダイアログの外にある場合、それ以上のイベントはありませんでした
  3. クリックがダイアログ内であった場合、focusinイベントが続きました

focusoutそのため、一連の->があると、望ましくない動作が発生しましたfocusindeferこの問題に取り組むために、アンダースコアの機能とブール修飾子を使用しました

onFocusout: function(event) {
  console.log('focus out');
  this.hasFocus = false;
  var self = this;
  _.defer(function() {
    if (!self.hasFocus) alert('DESTROY DIALOG');
  });
},

onFocusin: function() {
  console.log('focus in');
  this.hasFocus = true;
},

deferコール スタックがクリアされるまで関数を待機させ (不適切な動作の場合、focusinスタック内で待機しているイベントがあります)、それを実行します。そのため、変数が に変更されonFocusinた直後に が起動され、遅延関数がダイアログを破棄することはありません!onFocusouthasFocustrue

回答ありがとうございます。

4

5 に答える 5

6

おそらくより適切に機能するオプションは、ページ上の任意の場所でクリックをリッスンし、ダイアログ領域の外でクリックが発生した場合はダイアログを閉じることです。何かのようなもの:

$(document).on("click", function(e) {
    var clickedOnDialog = $(e.srcElement)
         .closest(".ui-widget.ui-dialog") // these classes are fixed
         .children(".ui-dialog-content") // this as well
         .is(".dialog"); // this is your own class

    if (!clickedOnDialog) {
        $('.dialog').dialog('destroy');
    }
});

デモ

于 2012-09-13T08:18:21.237 に答える
1

参考までに、jQuery モーダル ダイアログの場合、ui-widget-overlayコンテンツの上にクラスを含む div を配置します。したがって、私は次のようなことをしました:

$(".ui-widget-overlay").live("click", function() {
    $("#myDialogDiv").dialog("close");
});

それは魅力のように機能します:)

于 2012-12-13T19:51:24.557 に答える
0

ぼかしはあなたのために働くはずです:

$('.dialog').trigger('click');
$('.dialog').blur(function() {
   this.dialog('destroy');
}
于 2012-09-13T08:40:18.433 に答える
0

これが私の回避策です。複数のダイアログを含むページでも機能し、jquery の「ライブ」メソッドのソリューションも更新されています。

$(document).on('click', '.ui-widget-overlay', function() {
    var dialogAria = $(this).next().attr('aria-describedby');        
    $('#'+dialogAria).dialog("close");
});

私はスコットの答えに触発されました

于 2013-04-04T12:18:21.860 に答える
0

jQuery を使用すると、これはかなり簡単です。jQuery がダイアログを構造化する方法は、ダイアログがアクティブになるたびに、他のすべてのページ コンテンツをカバーし、.ui-widget-overlay のクラスを持ち、x の z-index を持つ div を配置することです (私のケース、100)。ダイアログがアクティブになるたびに、そのダイアログとそのダイアログに x + 1 の z-index のみが与えられます。

$(document).on('click', '.ui-widget-overlay', function () {
    var overlay = $(this);
    var dialogToClose = null;
    $.each($(".dialog"), function () {
        if ($(this).zIndex() == (overlay.zIndex() + 1)){
            dialogToClose = $(this);
        }
    });
    dialogToClose.dialog("close");
});
于 2015-06-08T16:56:57.560 に答える