islands5 blog

日々起こったことを共有したり、思ったこと、勉強したことを書いていくブログ。普段はRailsやAWSを活用したWeb系の開発をやってます。

【javascript】window.onloadを使うと思わぬエラーに遭遇するからヤメよう!!時代はaddEventListenerだ!!

htmlのレンダリングが完了してから処理を行ってほしい場合に、「window.onloadを使うと良いよ」という記事を見かける。
実際に「html 読み込み後 javascript」と検索すると(2016/5/30現在)一番上にこの方法が出てくる。

しかし、この方法だと思わぬバグに遭遇するかもしれないので注意したほうがいい。

よくある例

window.onload = function(){
  マークアップを色々操作する処理(jqueryとか使ってたり)
}

この記述があまりよろしくない。
何がよろしくないかというと、以下の例を見てほしい。

window.onload = function(){
  console.log("hoge");
}

window.onload = function(){
  console.log("fuga");
}

この場合、実行されるのは後ろで宣言されているconsole.log("fuga")だけである。
今回のように、近くで宣言している場合はすぐに気付けるが、別のファイルで呼ばれていたりするとなかなか気がつかないと思う。

ではどうすればいいか??

window.addEventListener("load", function(){
  console.log("hoge");
}, false)

window.addEventListener("load", function(){
  console.log("fuga");
}, false)

このようにすれば、ちゃんと2つのconsole.logが実行される。
意図的にwindow.onloadを使うなら大丈夫だと思うのですが、基本的にはaddEventListenerを使ったほうがいいと思う。

ちなみにIE9より前のブラウザでは、window.addEventListenerが定義されていない。
似たような機能として、attachEventがあるので、これを上手く使ってaddEventListenerを作ってしまえます。
イベント名が"load"でなく"onload"になったりする部分と引数が2つになる部分を修正すればOK

if( typeof window.addEventListener === "undefined") {
  window.addEventListener = function(event, listen, useCapture) {
    window.attachEvent("on" + event, listener);
  }
}

グローバルオブジェクトのwindowを直接変更するのは、ちょっと危ないので、
以下のような形がベターです。  

(function(w) {
  if (typeof w.addEventListener === "undefined") {
    w.addEventListener = function(event, listener, useCapture) {
      w.attachEvent("on"+event, listener);
    }
  }
  ~addEventListenerを使った処理
})(window);

ちょっと面白い気づきだったので、メモしました。

ではでは