質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.37%

  • JavaScript

    11190questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    4883questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

【JQuery】Uncaught ReferenceError: $ is not defined

解決済

回答 4

投稿 2017/11/30 09:27

  • 評価
  • クリップ 0
  • VIEW 291

teratailler

score 15

 やりたいこと

ページを表示した時、JQueryがロードされた段階で必ずスクリプトを実行したいです。
ページ表示段階でJQueryがロードされていなければスクリプトを実行しないというエラー回避ではなくJQueryがロードされた段階で必ずスクリプトを実行したいという要件になります。

 困っていること

以下のようなHTMLがあります。(簡略化しています)

<ul class="users">
  <li>Michael</li>
  <li>Daniel</li>
  <li>John</li>
</ul>

<script>
$('.users').each(function(index, user) {
    console.log($(user).text());
});
</script>


これをスーパーリロードすると、以下エラーがコンソールに出力されます。
※スーパーリロードしない時はキャッシュが有効なのでエラーが起こりません。

Uncaught ReferenceError: $ is not defined


JQueryがロードされる前にスクリプトが実行されていることはわかるのですが、これの対応策が調べてもわかりませんでした。
これを以下のようにすればエラーを回避できることがわかりましたが、エラー回避ではなくJQueryがロードされた段階で必ずスクリプトを実行したいというのが今回の要件になりますのでマッチしませんでした。

<ul class="users">
  <li>Michael</li>
  <li>Daniel</li>
  <li>John</li>
</ul>
<script>
if (typeof jQuery != "undefined") {
    $('.users').each(function(index, user) {
        console.log($(user).text());
    });
}
</script>

「待つ」という手段としてsetIntervalというものがあることも知りましたが、この要件への当てはめ方が調べてもわかりませんでした。

すみませんがよろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • defghi1977

    2017/11/30 09:30

    jQueryを読み込んでいるscript要素もコードに追加して下さい

    キャンセル

  • masaya_ohashi

    2017/11/30 09:32 編集

    なぜjQueryが読み込まれた直後でないといけないのかの説明もお願いします。window.onloadのタイミングでは駄目な理由もお願いします。

    キャンセル

  • defghi1977

    2017/11/30 09:36

    多分defer属性がついている

    キャンセル

  • yambejp

    2017/11/30 09:37

    jQueryが読まれているかどうかをチェックするより、事前に読むことが肝要なのでは?関係ソースをロードしておいてあとからjQueryをロードしたいのかもしれませんが、メリットが感じられません

    キャンセル

回答 4

+4

以下は推測です.


おそらくjQueryを読み込んでいるscript要素にdefer属性が付与されていることが原因です. 

defer属性はスクリプトの読み込みをdocumentDOMContentLoadedイベントが発生する前までに完了することを指定(保証)するものです. 一般にscript要素が参照するスクリプトコードは同期的に実行されるため, 複数のコードを参照している際にどうしてもWEBページのロードに時間がかかります. そこでdefer属性を指定しておくとWEBページ読み込みの背後でスクリプトが同時並行的に処理され, WEB応答性がよくなるのです. 

さて, あなたのコードではDOMノードの展開直後(DOMContentLoadedイベント発生前)にscript要素を配置してすぐにjQuery要素を使おうとしています. すると, スーパーリロード直後のタイミングではdefer属性によりjQueryコードのダウンロードと同時にスクリプトが実行されることとなり, 変数jQueryが見つからないことになるのです.

改善策としては次の2つが挙げられます.

  • defer属性を削除する
    jQueryの読み込みを同期的に行うことで, (script要素の配置が正しい限り)jQueryの読み込み後にあなたのコードが実行されるようになります. その代償としてWEB応答性が(多少)犠牲になります.
  • スクリプトの実行をDOMContentLoadedイベントの発生まで待つ
    DOMContentLoadedイベントが発生した後であればjQueryの初期化が完了していることが保証されていますから, あなたのコードは正しくjQueryを使えることになります.

後者を選択するのであれば, おそらくコードは次のようになるでしょう.

document.addEventListener("DOMCotnentLoaded", function(){
    $('.users').each(function(index, user) {
        console.log($(user).text());
    });
});

投稿 2017/11/30 09:57

編集 2017/11/30 11:05

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/30 10:14

    $で遅らせるのでは、その$が揃う前に「$(function(){...})」のコードが読まれてしまう以上、タイミングが良くないと間に合いません。

    jQueryをdeferで読み込むこと自体、(jQueryをサブにしか使わないシチュエーションなら話は別ですが)かなり使いにくいとは思います。

    キャンセル

  • 2017/11/30 10:59

    言われてみればそのとおり. 修正します.

    キャンセル

checkベストアンサー

+3

基本的には、(特に、jQueryで動かすウィジェットをページ内に置いてあって、表示も変化するような場合)jQuery本体の読み込みにdeferを付けるのはあまりおすすめしません。

そして、$(function(){...})内に書かれたコードは、結局DOMContentLoadedのタイミングで実行されますので、「jQueryの読み込み直後」に実行してもほとんど意味はありません。

本当にどうしてもやりたいのなら、「$がそろうか監視する」「jQueryの読み込みタグもJavaScriptで生成して、そのloadイベントに仕掛ける」などの手段が考えられます。

// <script>内の想定
(function main(){
  if(!window.$) {
   setTimeout(main, 50);
   return;
  }
  // ここまで来たときには確実に$がある
  $(function(){
    // 後略
  });
})();

投稿 2017/11/30 10:24

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

<ul class="users">
  <li>Michael</li>
  <li>Daniel</li>
  <li>John</li>
</ul>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
if (typeof jQuery != "undefined") {
    $('.users').each(function(index, user) {
        console.log($(user).text());
    });
}
</script>


これではダメなのですか?

投稿 2017/11/30 09:41

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

jqueryロードと同時に動かすモジュールpreload.jsがあったとして、jqueryやpreload.jsをdererでロードしたいということならpreload.jsとjqueryの依存関係をbrowserifyで(実行時ではなくビルド時に)マージすることで解決する手もあると思います。

preload.js

var $ = require('js/jquery-...min.js').$;

$( ... ) // DOM構築前に何かするならここに(できることあるのかな...)

$(function () {
  // DOM構築後の処理はこちらに
  if (typeof jQuery != "undefined") {
    $('.users').each(function(index, user) {
      console.log($(user).text());
    });
  }
});


==>jqueryとマージしたものがbuild.jsになったとすると以下のように巨大な他のJSファイルと並行してロードすることはできそうです。

...
<script type="text/javascript" defer src="js/build.js"></script>
<script type="text/javascript" defer src="js/heavy1.js"></script>
<script type="text/javascript" defer src="js/heavy2.js"></script>
...

なお例えばjquery.xxx.min.jsだと90KBほどだと思います。90KBのロードが与える性能の影響がどのくらいのものか自分にわかってないのですが、heavyN.jsのロード時間が性能を支配する主要因ならjquery/preloadのみ同期的にロードするdefghi1977さんの方法が自然に感じます。

トンチンカンなことを言っていたらご容赦ください。

投稿 2017/11/30 10:33

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.37%

関連した質問

  • 解決済

    jqueryでhtml要素の比較

    お世話になります。 jqueryでその要素がinputまたはselect要素なのかを比較したいときの方法がわからないので、教えていただきたいです。 $('input,s

  • 解決済

    jQuery ID属性取得がうまくいかない

    下記コードの$('input[name = bbs]').on('click',function()から処理で、bbsをclickした時に変数myidでradioのidを取得、変数

  • 解決済

    jQueryでチェックボックスの判定ができない

    チェックボックスにチェックをつけるとdisabledが無効になる機能を実装したいのですが、 チェックボックスの判定がうまく取得できません。 HTML側 <input ty

  • 解決済

    範囲を指定して文字を削除したい

    <br>から<span>の前までを削除して、名前だけにしたいです。 <li> <p class="name"> 名前<br>苗字 <span>出

  • 受付中

    外部JSファイルの実行後に実行

    以下のようなコードで、セレクトボックスの変更によって、 ★の処理を実行したいのですが、 ページ最下部にある外部JSの処理が最後に行われてしまい、 ★の処理が完了後に外部JSの処理で

  • 解決済

    jQueryでの年計算について

    jQueryでプルダウンの年計算を作っているのですがどうしてもわからないところがあります。 $(function() { for (var i = 2017; i >= 190

  • 解決済

    jqueryのdieとliveについて

    $(document).ready(function(){ $("#hogehoge").die("change"); $("#hogehoge").live("c

  • 受付中

    ページトップにスクロールできません

    実装したい内容・問題点 ・jQueryを用いてページの一番上までスクロールするボタンを作成したい ・https://syncer.jp/jquery-to-top-buttonやh

同じタグがついた質問を見る

  • JavaScript

    11190questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    4883questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。