【jQuery の ready(), load() が実行されずにハマった話】<script> に defer を指定した際、インラインのscriptはHTMLパース中に実行される

下記のうち、1, 2, 3 が実行されない原因がわからずハマりました。

<html>
<head>
    <script src="jQuery本体をロードするjsファイル" defer></script>
</head>
<body>

〜 略 〜

  <script>
    // jQuery の ready()
    jQuery(document).ready(function(){ //Uncaught ReferenceError: jQuery is not defined
      console.info('== 1 ==')
    });
  </script>

  <script>
    // jQuery の load()
    jQuery(window).on('load',function(){ //Uncaught ReferenceError: jQuery is not defined
      console.info('== 2 ==')
    });
  </script>

  <script>
    // 即時関数 (に引数で jQuery を渡す)
    (function($){
      console.info('== 3 ==')
    })(jQuery); //Uncaught ReferenceError: jQuery is not defined
  </script>

  <script>
    setTimeout(function() {
      console.info('== 4 ==')
    }, 2000)
  </script>

  <script>
    window.onload = function () {
      console.info('== 5 ==')
    }
  </script>

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      console.info('== 6 ==')
    });
  </script>

原因

<script src="jQuery本体をロードするjsファイル" defer>defer を指定している事が原因でした。

  • defer
    • HTML パース完了後に script が実行される
    • インラインの script はHTMLパース中(依存関係にあるjsファイルの実行前)に実行される
      • jQuery 本体が実行前なので、jQuery の ready関数, load関数 が実行できなかった

参考エントリー