Mach3.laBlog

jQueryUIのDialogをカスタマイズする6つの物凄く細かい小技

この記事は賞味期限切れです。(更新から1年が経過しています)

jQueryUIdialogは結構お世話になっているのですが、たまに欲しい機能がなかったり、あっても説明されてなかったりするのでここにDialogカスタマイズTipsをしたためておきます。

この記事の内容は既に古くなっています。現在最新バージョンのjQueryUIでは挙動が改善されていたり、渡せるオプションが変わっていたりします。

jQueryUIのDialogをカスタマイズする6つの物凄く細かい小技

  1. Modalしたダイアログをオーバーレイクリックで閉じる
  2. 任意の要素をクリックして閉じる
  3. アニメーションで閉じる・開く
  4. エフェクト中にオーバーレイの後ろに回りこんでしまうのを回避する
  5. 閉じる・開くアニメーションにパラメータを渡す
  6. 閉じるついでにデストロイする

1. Modalしたダイアログをオーバーレイクリックで閉じる

Modalしたダイアログをオーバーレイクリックで閉じる

escキー押下で閉じるオプションはあるのですが、このオプションはない様子。 そこで、こんな感じで実装してみます。

$(document).on("click", ".ui-widget-overlay", function(){
    $(this).prev().find(".ui-dialog-content").dialog("close");
});

ダイアログを紐付けた要素には ui-dialog-content クラスが付加されていて、 その要素に対して .dialog(“close”) する事でダイアログを閉じる事が出来ます。

オーバーレイと本体との位置関係は、

( .ui-dialog > .ui-dialog-content ) + .ui-widget-overylay

みたいな感じでオーバーレイの方が後。

尚、オーバーレイ付きのダイアログの表示はmodalオプションで出来ます。

$("#myDialog").dialog({
    modal : true
});

2. 任意の要素をクリックして閉じる

例えば中にあるボタンをクリックするとダイアログを閉じるようにしたい。

まずHTMLにてボタンを設置。

<div id="myDialog">
    <p>下のボタンをクリックして閉じてね!</p>
    <p><input type="button" class="dialog-button-close" value="CLOSE" /></p>
</div>

こんな感じで実装。
やっている内容はオーバーレイの例と同じです。

$(document).on("click", ".ui-dialog .dialog-button-close", function(){
    $(this).closest(".ui-dialog-content").dialog("close");
});

3. アニメーションで閉じる・開く

ダイアログを開く際、または閉じる際にアニメーションを付加します。
これは公式ドキュメントにも記載されていますが、ややわかりづらかったので。

例えばフェードイン・アウトで開閉をしたい場合。

$("#myDialog").dialog({
    show : "fade",
    hide : "fade"
});

このように、showオプションとhideオプションに使いたいエフェクト名を渡せばOK。
エフェクト名は、jQueryUIのEffectsコンポーネントの物が使用できます。
個人的にはclipとか好きです。

Possible values: ‘blind’, ‘bounce’, ‘clip’, ‘drop’, ‘explode’, ‘fold’, ‘highlight’, ‘puff’, ‘pulsate’, ‘scale’, ‘shake’, ‘size’, ‘slide’, ‘transfer’.

cf) jQuery UI – Effect Demos & Documentation

4. エフェクト中にオーバーレイの後ろに回りこんでしまうのを回避する

showオプションとmodalオプションを一緒に使うと、エフェクト中、オーバーレイの後ろにダイアログが回りこんでしまい、若干気持ち悪い動きになってしまいます。

動きの詳細を見てみると、エフェクト中のダイアログが一旦 .ui-effects-wrapper というコンテナに格納され、アニメーション完了時に .ui-dialog に移されています。

問題なのはこの .ui-effects-wrapper のz-indexが、 オーバーレイ( ui-widget-overlay )よりも小さい点。 .ui-effects-wrapper が1000、.ui-widget-overlay が1001、.ui-dialog が1002です。

(少なくとも私が)想定する動きにする為には、 オーバーレイのz-indexをエフェクトのコンテナよりも小さくしてあげれば良いです。

$("#myDialog").dialog({
    show : "fade",
    hide : "fade",
    modal : true
});
$(".ui-widget-overlay").css("z-index", 999);

5. 閉じる・開くアニメーションにパラメータを渡す

上記のshow/hideのエフェクトにパラメータを渡したい。 例えば、アニメーションの時間や完了時のコールバックを設定したいケースがあります。

公式ドキュメントでは、 「show/hideにはObjectを渡す事も出来る」という旨の記載しかありませんでした。 で、$.animate()にならって適当に突っ込んだら出来ました。

$("#myDialog").dialog({
    show : {
        effect : "fade",  // エフェクト名
        duration : 500,  // アニメーションの時間
        complete : function(){  // 完了時のコールバック
            alert("Dialog is opened");
        }
    }
});

ちょっと引っ掛けられてしまったのですが、オプションのキーが jQueryUIのEffectコンポーネントのドキュメントにある引数名と違うので注意です。

6. 閉じるついでにデストロイする

既に設置された要素に対して $(ele).dialog() するのであれば問題はありませんが、 動的に生成した要素でダイアログを表示していると、どんどんゴミが溜まっていきます。 例えばこんな感じにダイアログを表示していくと…

$('<p>').text("This is dialog.").dialog();

表示して消す度に、 ドキュメントの最後に

<div class="ui-dialog ...">

が量産されていきます。 この場合、これはその後再利用される事はない純然たるゴミです。
別にあって困るものではないかもしれませんが、やっぱり気持ち悪いので
ダイアログを閉じる際についでに削除してみます。

$('<p>').text("This is dialog.").dialog({
    close : function(){
        $(this).dialog("destory").remove();
    }
});

全てのダイアログに対して行う

もし、全てのダイアログのコンテンツが動的に生成された要素である保証があるのなら、 バブリングを利用すればまとめて処理できますね。

$(document).on("dialogclose", ".ui-dialog-content", function(){
    $(this).dialog("destroy").remove();
});

勿論、もし前述のような保証がないのならば、そうすべきではありません。想定外の要素が削除されてしまいかねないので。

まとめ

lightbox系のライブラリは色々リリースされていますが、 自分の中のスタンダードを決めておいてしっかりと中身を理解しておくと、 細かい対応が出来るようになりますね。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*

Berthac56d4d67593db49df2763dfea2cf8bd7
Which came first, the problem or the sonloitu? Luckily it doesn't matter.