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

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

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

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

Q&A

解決済

1回答

471閲覧

JavaScript $.whenの中で行っているDOM操作が後から実行される

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

0グッド

1クリップ

投稿2018/07/26 10:33

JavaScriptで下記のような処理を行いたいと思っています。
(1)ボタンを押下するとモーダルウィンドウが開く。
(2)モーダルウィンドウ内のボタンを押下すると、モーダルウィンドウ内にローディングバーが表示される。
(3)バックグラウンドでAjax(同期通信)を行う。
(4)(3)の通信完了後、モーダルウィンドウが自動で閉じる。

この部分の処理がどうしても下記のようになってしまい、困っています。
(1)ボタンを押下するとモーダルウィンドウが開く。
(2)モーダルウィンドウ内のボタンを押下すると、ローディングバーが表示されないままAjax通信が実行される。
(3)通信完了後、モーダルウィンドウが自動で閉じる。

プログラムは下記のように書いています。
(業務で書いているプログラムなので、業務にかかわる部分は伏せて書かせていただきます。
分かりづらいところなどございましたら申し訳ありません。)

JavaScript

1 // (1)のモーダルをDOMで作成 2 var select = $("<select>").addClass("col-xs-12"); 3 $.each(foo, function(hoge, fuga) { 4 select.append($("<option>").val(hoge).text(fuga)); 5 }); 6 var modal = $("<div>"); 7 modal.append(select); 8 9 modal.dialog({ 10 "modal":true, 11 "draggable":false, 12 "closeOnEscape":false, 13 "buttons": [ 14 { 15 text: "通信開始", 16 type: "button", 17 click : function() { 18 var hoge = function() { 19 var loading = $("<div>") 20 .addClass("progress progress-striped active") 21 .append($("<div>") 22 .addClass("progress-bar") 23 .css("width", "100%") 24 ); 25 $(".ui-dialog-content").prepend(loading); 26 } 27 $.when( 28 hoge() 29 ).done(function() { 30 // ajax通信(同期通信)の処理 31             hogehoge(); 32 33 // ウィンドウを閉じる 34 $(this).dialog("destroy").remove(); 35 }); 36 } 37 }, 38 { 39 text: "キャンセル", 40 type: "button", 41 click : function() { 42 // ウィンドウを閉じる 43 $(this).dialog("destroy").remove(); 44 }, 45 }, 46 ] 47 });

.done()処理内の$(this).dialog("destroy").remove();を削除したところ、下記のような動作となったため、
標題の「$.whenの中で行っているDOM操作が後から実行される」という動きになっていることが判明しました。
(1)ボタンを押下するとモーダルウィンドウが開く。
(2)モーダルウィンドウ内のボタンを押下すると、ローディングバーが表示されないままAjax通信が実行される。
(3)Ajax通信完了後、ローディングバーが表示される。

なお、$.whenの中にalert('hoge');console.log('hoge');を記載した場合、
Ajax通信の前にそちらが実行されますので、DOM操作だけが実行されないようです。
また、同期通信の箇所を非同期通信にしても結果は変わらなかったため、同期通信が原因というわけでもないのかな…と考えております。

「こういうところが原因ではないか」というようなヒントやアイデアだけでもいただけると幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

whenするときに$.Deferred()をつかってhogeの戻り値で
resolve()をreturnしてみてはどうでしょうか?

追記

ごめんなさいちょっと違いました

javacript

1var d = new $.Deferred(); 2$.when(d).done(function(){ 3 hogehoge() 4}); 5 (function(d){ 6 var loading = $("<div>") 7  .addClass("progress progress-striped active") 8  .append($("<div>") 9  .addClass("progress-bar") 10  .css("width", "100%") 11 ); 12 $(".ui-dialog-content").prepend(loading); 13 d.resolve(); 14 )(d); //hoge()の部分 15}

投稿2018/07/26 10:37

編集2018/07/26 12:19
yambejp

総合スコア114574

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

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

退会済みユーザー

退会済みユーザー

2018/07/26 11:16 編集

回答ありがとうございます! さっそくhoge()の中身を下記のように書き換えてみましたが、動作は変わりませんでした。 var hoge = function() {   var d = new $.Deferred();   var loading = $("<div>")     .addClass("progress progress-striped active")     .append($("<div>")       .addClass("progress-bar")       .css("width", "100%")     );   $(".ui-dialog-content").prepend(loading);   return d.resolve(); } return d.resolve()を下記のように書き換えても同様でした、   d.resolve();   return d.promise();
yambejp

2018/07/26 12:20

d.resolve()はreturnしないで大丈夫です $.when()で実行させるのは事前にインスタンスにしたd
退会済みユーザー

退会済みユーザー

2018/07/28 18:02

コードまでいただいてありがとうございます…!返信遅くなってしまい申し訳ありません。 こちらも試させていただきましたら、動作は変わりませんでした……。 調べたところ、他の箇所でもオブジェクトを対象としたプログラムは後から実行されるようでしたので、 プロジェクトの他のコードのどこかに原因があるのかもしれません。 いったん業務では今回の仕様の実装は保留としましたが、 yambejp様の回答のおかげで$.when().done()の使い方を具体的に理解することができました! ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問