SPAサービスを作る時や、ASPサービス、APIサービスなどを構築する時に、WEBアプリケーションには、インターネット先からのダウンロード処理があるため、基本となるベースのHTMLソースが読み込まれてから、それぞれの処理を開始させる必要があります。
そんな時、「onload」イベントを使って処理をすれば大体の事は解決するのですが、サービス形態によっては、「DOMContentLoaded」を使った方がいい場合や、そのイベントの特性を理解しておかないと、トラブルにつながります。
インターネットサービスにおけるloadイベントを少し掘り下げてみたく色々とまとめてみました。
onloadとDOMContentLoadedのそれぞれの使い道
「onload」は、ページが読み込まれた時に発火するイベントですが、scriptやlinkタグのcssソースなども読み込みが完了した後での発火になるので、モジュールの読み込みも完了している必要があるサービスで有効です。
https://developer.mozilla.org/ja/docs/Web/Reference/Events/load
「DOMContentLoaded」は、HTMLソースが読み込まれてDOMga構築された状態で発火するイベントです。
onloadよりも、早く発火できるため、スピード重視のサービスでは、利用するケースが多いようです。
https://developer.mozilla.org/ja/docs/Web/Reference/Events/DOMContentLoaded
よくあるASPサービスで</body>の直前に記述することが必須のサービスは、onloadを回避するために行なっている場合が多いのですが、htmlで本来推奨されているのは、scriptタグなどは、headタグ内に記述するという事なのですが、CMSなどの仕組みでそうできない場合も少なくないようです。
厳密にどちらのイベントを使えばいいかは、判断が難しい場合が多いのですが、DOMContentLoadedを使う事を基本にした方がいいようですね。
ちなみに、loadイベントは、imgタグなどで、画像が読み込まれたときの発火などにも使えるので、使い慣れるとかなりインタラクティブなページが作れますよ。
まあまあ使えるソースコード
scriptタグの起動時に、下記のソースコードを基準に起動するとまあまあ便利に起動確認をしながら、確実にイベントをキャッチしてサービス起動タイミングを調整してくれるので、便利に使ってます。
var state = document.readyState;
if(state === "complete"){
set();
}
else if(state === "interactive"){
this.setEvent(window , "DOMContentLoaded" , set);
}
else{
this.setEvent(window , "load" , set);
}
function set(){
console.log("起動しました。");
}
このプログラムをJSファイルの起動処理にしておくと、HTMLファイルのどのポジションに書いてもちゃんとsetが読み込まれる上、ページload以後に外部から読み込まれたscriptにおいても、ちゃんとset()が実行される判定をしているので、確実にプログラム起動ができ、かつ、ページ読み込み完了判定に対応しているので、非常に便利に使えます。
上書き注意
loadイベントやDOMContentLoadedイベントを使う時に注意しなければいけない事は、便利な外付けサービスで行いたい時に"window.onload = function(){...}"としてしまうと、既存にセットされていたイベントが会った時は上書きしてしまうというバグに繋がってしまいます。
"addEventListener"を使って対応すればいいのですが、IEでうまく動かない事はエンジニアの悩みの種ですね。
そこで、下記のソースコードを使う事で、それも解消できるので、合わせて使ってみてください。
function setEvent(target, mode, func){
if (target.addEventListener){target.addEventListener(mode, func, false)}
else{target.attachEvent('on' + mode, function(){func.call(target , window.event)})}
};
// 使い方
setEvent(window , "DOMContentLoaded" , set);
setEvent(window , "load" , set);
0 件のコメント:
コメントを投稿