質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Q&A

解決済

1回答

10908閲覧

bootstrapを素早く開閉した際の不具合

sk_3122

総合スコア1126

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

1グッド

2クリップ

投稿2017/10/16 03:46

編集2017/10/16 04:21

こんにちは。Bootstrap の modal についての質問です。
よろしくお願いします。

[jquery 1.10.2]
[bootstrap 3.0.0]

[Windows10 / IE11, Chrome]
[Android 7.0]

###発生している問題

bootstrap の modal を使用する際、
「modalを閉じた後、閉じきる前に素早く 再度modalを表示する」
という操作を行うと、modal が開かなくなってしまう現象が起きています。
(IEの開発者ツールで確認したところ、javascriptエラーは発生していないようです)

# 元々、modal の上に modal を出していて、そのせいかと思っていたのですが
# サンプルを作ってみたところ そうでなくても発生するようです?

html

1<!DOCTYPE html> 2<html> 3<head> 4<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css"> 5<style> 6 7 /* 連打しやすいようにボタンを大きくしているだけ */ 8 #btnShowOya { max-width: auto; width:100%; box-sizing:border-box; height: 200px; } 9 #btnShowKo { max-width: auto; width:100%; box-sizing:border-box; height: 200px; } 10 #btnCloseKo { max-width: auto; width:100%; box-sizing:border-box; } 11 12 /* 子ダイアログの横幅を親より広くする。後ろに隠れているとかではないよね?という確認用 */ 13 #KoDialog .modal-dialog { 14 position:relative; 15 right: auto; 16 left: 50%; 17 width: 750px; 18 margin-left: -375px; 19 } 20 21</style> 22<title>TEST</title> 23</head> 24<body> 25 26 <div class="container"> 27 28 <!-- 親ダイアログ呼び出しボタン --> 29 <button id="btnShowOya" class="btn btn-primary">show OYA</button> 30 31 </div> 32 33 <!-- 親ダイアログ --> 34 <div class="modal fade" id="OyaDialog" data-backdrop="static" data-keyboard="false"> 35 <div class="modal-dialog"> 36 <div class="modal-content"> 37 <div class="modal-header"> 38 <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> 39 <h4 class="modal-title">親ダイアログ</h4> 40 </div> 41 <div class="modal-body"> 42 <div class="row"> 43 <div class="col-xs-12"> 44 親です 45 </div> 46 <div class="col-xs-12"> 47 <button id="btnShowKo" class="btn btn-primary">show KO</button> 48 </div> 49 </div> 50 </div> 51 <div class="modal-footer"></div> 52 </div> 53 </div> 54 </div> 55 56 <!-- 子ダイアログ --> 57 <div class="modal fade" id="KoDialog" data-backdrop="static" data-keyboard="false"> 58 <div class="modal-dialog"> 59 <div class="modal-content"> 60 <div class="modal-header"> 61 <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button> 62 <h4 class="modal-title">子ダイアログ</h4> 63 </div> 64 <div class="modal-body"> 65 子です 66 </div> 67 <div class="modal-footer"> 68 <div class="row"> 69 <div class="col-xs-8 col-xs-push-2"> 70 <button id="btnCloseKo" class="btn btn-primary">OK</button> 71 </div> 72 </div> 73 </div> 74 </div> 75 </div> 76 </div> 77 78</body> 79<script src="https://code.jquery.com/jquery-1.10.2.js"></script> 80<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script> 81<script> 82 $(function() { 83 84 // 親ダイアログ表示ボタン 85 $("#btnShowOya").on("click", function() { 86 if (window.console) console.log("◆親を表示"); 87 $("#OyaDialog").modal("show"); 88 return false; 89 }); 90 91 // 子ダイアログ表示ボタン 92 $("#btnShowKo").on("click", function() { 93 if (window.console) console.log("★子を表示"); 94 $("#KoDialog").modal("show"); 95 return false; 96 }); 97 98 // 子ダイアログCLOSEボタン 99 $("#btnCloseKo").on("click", function() { 100 if (window.console) console.log("☆子を閉じる"); 101 $("#KoDialog").modal("hide"); 102 return false; 103 }); 104 105 $(".modal").on('hidden.bs.modal', function () { 106 // modal-backdrop があったら削除する 107 $(this).find(".modal-backdrop").remove(); 108 109 // モーダルの上にモーダルを開いた場合に必要な処理 110 // まだ他に開いているモーダルがある場合、bodyにmodal-openを設定(親ダイアログのスクロールを復活させる為に必要) 111 if ($(".modal-dialog:visible").length > 0) { 112 $('body').addClass('modal-open'); 113 return false; 114 } 115 }); 116 117 // イベント発生確認用 118 $("#KoDialog").on('hide.bs.modal', function () { 119 if (window.console) console.log("* hide.bs.modal"); 120 return true; 121 }); 122 $("#KoDialog").on('hidden.bs.modal', function () { 123 if (window.console) console.log("* hidden.bs.modal"); 124 return true; 125 }); 126 $("#KoDialog").on('show.bs.modal', function () { 127 if (window.console) console.log("* show.bs.modal"); 128 return true; 129 }); 130 $("#KoDialog").on('shown.bs.modal', function () { 131 if (window.console) console.log("* shown.bs.modal"); 132 return true; 133 }); 134 135 }); 136</script> 137</html> 138

###試したこと:modal-backdrop を自分で消してみました

IEの開発者ツールで DOM Explorer を見てみたところ、以下の事がわかりました。

  1. $.modal("show") を呼ぶと、modal直下に
<div class="modal-backdrop fade in"></div> が追加付与される。   2. $.modal("hide") を呼ぶと、上記 modal-backdrop は削除される。   3. 今回問題となっている、素早くmodal再表示を呼んだ際は、 モーダルが表示されていない状態で <div class="modal-backdrop fade"></div> が追加された状態となっていました。 (class="fade in" ではなく class="fade" となっているので、不可視だがbackdropは居る状態?)

上記を見て、
$(".modal").on('hidden.bs.modal', function(){}) にて
.modal-backdrop があったら消すようにしてみましたが、現象は変わりませんでした。

###確認したこと:イベントの発生順

log を仕込んでイベントの発生順を確認したところ、
通常の modal 表示時は show → shown,
通常の modal CLOSE時は hide → hidden
という順にイベントが発生していますが、問題のケースでは以下のようになっていました。

show → hide → hidden. (shown は無し)

以降 modal 表示ボタンを押しても、show は発生しますが shown まで行きません。

 
今回の現象はこのイベント発生順によるものだとは思うのですが...
そもそも、ダイアログが閉じきるまでは 親要素を触れなくすることはできないのでしょうか。
(hide ではなく hidden で触れるようにしたい?)

 
何か既出の解決方法等があるのではないかと思い質問させていただきました。
それとも bootstrap を自分で修正しないと駄目でしょうか...

以上です。よろしくお願いします。

KSwordOfHaste👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

bootstrap の modal は二重起動に対して前向きな対応をしていないようですね。

質問者さんが「確認したこと」でおっしゃるとおりイベントが
順序悪く混じってしまうことが問題なのでそれを回避してあげることで解決できるようです。

以下のコードに示すように2種類の状態フラグを管理します。

  • $(this).data('shown') -> 表示描画処理の完了フラグ
  • $(this).data('hidden') -> 非表示描画処理の完了フラグ

表示/非表示の開始イベント時にそのフラグを判定し完了状態になっていなければ、
順序悪いイベント自体をキャンセルすることで正常な順番で処理をするように強制してあげます。

javascript

1$("#KoDialog").on('hide.bs.modal', function () { 2 if ($(this).data('shown') === false) return false 3 if (window.console) console.log("* hide.bs.modal"); 4 return true; 5}); 6$("#KoDialog").on('hidden.bs.modal', function () { 7 $(this).data('shown', false) 8 $(this).data('hidden', true) 9 if (window.console) console.log("* hidden.bs.modal"); 10 return true; 11}); 12$("#KoDialog").on('show.bs.modal', function () { 13 if ($(this).data('hidden') === false) return false; 14 if (window.console) console.log("* show.bs.modal"); 15 return true; 16}); 17$("#KoDialog").on('shown.bs.modal', function () { 18 $(this).data('shown', true) 19 $(this).data('hidden', false) 20 if (window.console) console.log("* shown.bs.modal"); 21 return true; 22});

投稿2017/10/16 15:02

cookieman

総合スコア128

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sk_3122

2017/10/17 01:12

ありがとうございます…! なるほど、data で modal 自身にフラグを持たせて、return false でイベントを潰してやれば bootstrap 本体を弄らなくても外から制御できるんですね。思いつきませんでした... とても助かりました。ありがとうございます m(_ _)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問