電脳麻将UI 〜 牌 - koba::blog と 電脳麻将UI 〜 音声 - koba::blog で、電脳麻将 では牌の画像や音声データを「DOMをコピーして使う」と説明しましたが、画像や音声データをブラウザが読み込む前に使ってしまうと、ダウンロード中の画像が表示されたり音声が遅れて再生されたりします。jQuery では
$(function(){ /* ... */ })
の中にプログラムを書くことで、HTMLが読み込まれDOMが構成されるより前にアプケーションが実行されるのを避けるのが「作法」となっていますが、このタイミングでDOMは完成していても外部リソースの読み込みは終わっていないことが多々あります。
外部リソースの読み込みを待つために window の load イベント を使用することができます。電脳麻将では以下のような実装で、タイトル画面を出して外部リソースの読み込みを待ち合わせしています。
const { show, hide } = Majiang.UI.Util; let loaded; function start() { /* アプリケーションを開始する */ }; $(function(){ $(window).on('load', function(){ /* 外部リソースが読み込まれたら */ hide($('#title .loading')); // Loading... の表示を消す $('#title .start').on('click', start) // ハンドラを設定する show($('#title .start')); // START ボタンを出す }); if (loaded) $(window).trigger('load'); // すでに load が発生済みなら // 再度発生させる }); $(window).on('load', ()=> loaded = true);
DOMの完成より先に外部リソースの読み込みが終わる場合があるので(2度目以降のアクセスなど)注意が必要です。上記のプログラムでは、load イベントが先に発生したことを把握したら再発生させる実装となっています。
音声データに関しては preload の指定を無視するブラウザがほとんどですが、その場合は音声を読み込んでいなくても load イベントは発生します*1。音声がなくてもゲームは成立するので音声データの読み込みは「可能なら待つ」という考えで実装しています。
以下で実際の動作を確認できます。
*1:回線の遅いときなど待たない方がよい場合もあります