イベント処理の際にフォーム関連DOM処理を行うとイベント処理終了時にまとめてDOM処理が行われてしまうため、処理待機中にスピナーやプログレスバーの表示ができません。
例えば、「日付」選択イベントの際にその日付に該当する、あるアプリのデータを取得してフィールドにセットする、などの処理を行う際に、処理に時間がかかる場合がございます。
画面がフリーズした訳ではなく、処理中であることをスピナーや進捗状況を示すプログレスバーなどで示したいのですが、
ブラウザの開発者ツールでソースコードを追っていくと、このケースでは、どうやら開発者が書いたフォームとは関係のないDOM処理も含めてすべてのDOM処理がイベント終了時に行われているように見受けられます。
そのため、このようなケースでスピナーやプログレスバーの表示を行うことができません。
一方フォームに関するDOM処理がイベントハンドラ内に記述されない場合は正常にスピナーやプログレスバーを表示することができます。
この問題を回避する方法はありますでしょうか?
shiro さん
たぶん XMLHttpRequest による同期リクエストを使われているのではないでしょうか?
同期リクエストは、「実行中に画面がかたまり他の操作ができなくなる」という問題があります。
この問題の対応策として、kintone API におけるPromiseサポート があります。
Promise 処理にすると、スピナーやプログレスバーの表示が可能です。
kintone API で Promise を使ってみよう! に同期処理の問題点やPromise処理のコードがまとめられています。
他には、Promise関連 にリンクをまとめていますので、参考にしてください。
rex0220さん
ご返信ありがとうございます。
通信は原則的に非同期リクエストで行なっており、必要な場合にはPromise処理を利用しております。
ただし、プロセス処理や「保存」ボタンイベントの処理の際には、非同期リクエストで処理するとバックグラウンドで通信処理をしつつ、画面が固まらなくてすむというメリットがありますが、処理に時間がかかっている場合、見かけ上は処理が終わっているのに、実際にはバックグラウンドで大事な処理が続いているケースが多々あります。
そのようなケースでは、バックグラウンドで処理が続いている間に画面を閉じられてしまうと処理が中断してしまうため、Promiseを使ってイベント処理の終了を待たせています。
特にこうしたケースで上記の問題が発生しています。
スピナー、プログレスバー表示部分をPromiseで書いて、スピナー等の表示の終了を待ってから次の処理を行うようにも書き換えてみましたが、ダメでした。
※ 最初にあげた「日付」選択時の処理の場合は同期リクエストが使われていましたのでこちらのほうで改善の余地はあるかと思います。
追記:
上記の例の「保存」やプロセス処理ではイベント処理でフォーム関連のDOM処理を書くことがないので、問題は発生していません。自分の早とちりでした。
追記:
上記の「スピナー、プログレスバー表示部分をPromiseで書いて、スピナー等の表示の終了を待ってから次の処理を行うようにも書き換えてみましたが、ダメでした。」の部分は
Promiseを連鎖させる仕組みで書いてみたということです。
スピナー表示のPromiseがresolve() → 通信処理関係のPromise
といった感じですが、これでもうまくいきませんでした
こちらで開発したプラグインで、イベント処理でスピナー表示後、Promise処理を行っているものがありますが、問題なくスピナー表示されています。
何らかの問題がありそうですね。
よろしければ、処理コードを見せていただけますか?
rex0220さん
「ただし、プロセス処理や「保存」ボタンイベントの処理の際には、非同期リクエストで処理するとバックグラウンドで通信処理をしつつ、画面が固まらなくてすむというメリットがありますが、処理に時間がかかっている場合、見かけ上は処理が終わっているのに、実際にはバックグラウンドで大事な処理が続いているケースが多々あります。
そのようなケースでは、バックグラウンド処理で処理が続いているのに画面を閉じられてしまうと処理が中断してしまうため、Promiseを使ってイベント処理の終了を待たせています。
特にこうしたケースにおいて、イベント処理内にフォーム関連のDOM処理がある場合、上記の問題が発生しています。」
とお書きしたのですが、こちらの早とちりで、このようなケースではフォーム関連のDOM処理を入れることはないのでスピナーが表示できないという問題は発生していませんでした。
大変申し訳ありません。
問題が発生している箇所を再度調べてみたのですが、問題が発生している箇所はすべて同期リクエストが使われていました。非同期リクエストに書き換えて試してみます。
rex0220さん
問題が発生したアプリとは別に新たにテスト用のアプリを作成し、非同期リクエスト、同期リクエストの両方で取得したデータをフォームに反映させるという処理を実装しました。
テストしてみたところどちらのケースでも正常にスピナーが表示されたため、問題が発生していたアプリのコードに何らかの問題があるようです。
ソースコードはお客様向けのコードでしかも、かなり長いためここにお貼りすることはできないのですが、後ほど詳細に調査してみたいと思います。
ご対応ありがとうございました。