はじめに
kintoneの画面表示時に発生するイベントハンドラーの登録タイミングが遅いと、 そのイベントの発生を受け取ることができないケースがあります。
この記事では、
- kintoneの画面表示イベントが発生するタイミング
- イベントハンドラーの登録が遅い時の警告表示
- 適切なタイミングでイベントハンドラーを登録する書き方
について解説します。
kintoneの画面表示イベントが発生するタイミング
ブラウザが kintoneのページを読み込む時、kintone 本体のJavaScriptや、 カスタマイズによるJavaScriptは次の順番で実行されます。
- ブラウザがページのHTML読み込みを開始する
- kintone の JavaScript API を使うための初期化が行われる
- カスタマイズ JavaScript として登録されたスクリプトが読み込まれる
- kintone 本体の JavaScriptによるページ初期化処理が開始される
- ブラウザがページのHTMLを読み終わり、DOMContentLoadedイベント (※ 1) を発生させる
- HTMLで指定されている画像などのリソース読み込みが完了した後、ブラウザはloadイベント (※ 2) を発生させる
jQueryを使った場合など、慣例的なJavaScriptの書き方の一部には、5.のDOMContentLoadedイベントや 6.のloadイベントのイベントハンドラーで処理を始めるものがあります。
kintoneでは、これらのイベントよりも早い4.のタイミングで、kintone 本体の処理を始める方法を採用しています。
したがって、DOMContentLoadedイベントよりも、kintoneの画面表示イベントが先に発生することがあります (※ 3)。
イベントハンドラーの登録よりもイベントが先に発生した場合、イベントハンドラーは呼び出されません。
そのため、DOMContentLoadedやloadイベント内で、kintoneにイベントハンドラーを登録している場合、 それらが呼び出されないことがあります。具体的には、次のイベントが該当します。
- app.record.create.show
- app.record.edit.show
- app.record.detail.show
これらの画面表示時のイベントを確実にハンドリングするには、3. のカスタマイズ JavaScript が読み込まれた時に 同期的に、kintone.events.on()によりイベントハンドラーを登録してください。
※ 1 参考 (外部サイト): https://developer.mozilla.org/ja/docs/Web/Reference/Events/DOMContentLoaded
※ 2 参考 (外部サイト): https://developer.mozilla.org/ja/docs/Web/Reference/Events/load
※ 3 kintone は画面上に表示する多くのコンポーネントを JavaScript により描画しています。 そのため、ブラウザが発生させる DOMContentLoaded や load イベントの完了と、 kintone の DOM 構築が完了するタイミングには直接的な前後関係はありません。
警告の表示
kintone.events.on()によるイベントハンドラーの登録が、3.のカスタマイズ JavaScript が読み込まれた時に 同期的に実行されていない場合、次のような警告がブラウザの開発者コンソールに表示されることがあります (※ 4)。
この警告が表示された場合は、以降の書き方の例を参考にイベントハンドラーの登録タイミングの修正をお願いいたします。
※ 4 2018年7月版からの機能です。app.record.create.show、app.record.edit.show、app.record.detail.showの登録がない場合、または、 カスタマイズ読み込み時に適切なタイミングで登録されている場合は表示されません。
書き方の例
jQueryを使った書き方
良くない例
jQueryを使った慣例的な書き方の一つに、JavaScript での処理全体を$(() => {...});で囲んで書くというものがあります。
jQueryの仕様では、この書き方は DOMContentLoaded イベントのイベントハンドラー内で ... 部分を実行することに相当します。
前述のとおり、DOMContentLoaded イベントは、kintone 本体のJavaScriptによるページ初期化処理よりも後に実行されます。
したがって、この書き方では app.record.create.show イベントが発生するよりも、kintone.events.on()による イベントハンドラーの登録が後になってしまい、イベントハンドラーが呼び出されないことがあります。
良い例
少し複雑になりますが、jQueryのグローバル変数を捕捉する書き方と組み合わせると、次のようになります。
なお、カスタマイズの処理内容によっては、DOMContentLoaded イベントを待ってから処理を始める必要があるかもしれません。
その場合は、kintone.events.on()によるイベントハンドラーの登録と、$(() => {...}による処理を分けて書いてください。
一般的な例
jQueryを使わない場合も、app.record.create.showなどのイベントハンドラーの登録はカスタマイズの スクリプトが読み込まれた時に、同期的に実行されるように実装してください。
良くない例
- DOMContentLoadedのイベントハンドラー内で、app.record.create.showなどのイベントハンドラーを登録する
- loadのイベントハンドラー内で、app.record.create.showなどのイベントハンドラーを登録する
loadイベントは、DOMContentLoadedより、さらにあとに呼び出されるため、load イベントハンドラーでの登録も避けてください。
- その他、非同期リクエストのコールバックなど、非同期処理のコールバックで非同期に登録する
良い例
まとめ
画面表示時にkintoneが発生させるイベントのタイミングと、 それらのイベントを受け取るイベントハンドラーの適切な登録方法を紹介しました。
イベントハンドラーの登録タイミングが遅く、警告が表示されている場合も、一見問題なく動作する場合はあります。
しかし、ネットワークの遅延や、クライアントPCの性能、他のカスタマイズスクリプトの影響などにより、 非同期処理でのイベントハンドラーの登録が大きく遅延し、トラブルの原因となることがあります。
今回ご紹介した例を参考に、適切なタイミングでのイベントハンドラーの登録にご留意いただければ幸いです。
このTipsは、2018年7月版 kintoneで確認したものになります。
記事に関するフィードバック
記事のコメント欄は記事に対するフィードバックをする場となっております。
右の記事フィードバックのためのガイドを参照してコメントしてください。
記事のリンク切れなど、気になる点がある場合も、こちらのフォームからフィードバックいただけますと幸いです。