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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

jQuery

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

Q&A

解決済

4回答

2102閲覧

【JQuery】Uncaught ReferenceError: $ is not defined

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

jQuery

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

0グッド

1クリップ

投稿2017/11/30 00:27

やりたいこと

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

困っていること

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

Html

1<ul class="users"> 2 <li>Michael</li> 3 <li>Daniel</li> 4 <li>John</li> 5</ul> 6 7<script> 8$('.users').each(function(index, user) { 9 console.log($(user).text()); 10}); 11</script>

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

Uncaught ReferenceError: $ is not defined

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

Html

1<ul class="users"> 2 <li>Michael</li> 3 <li>Daniel</li> 4 <li>John</li> 5</ul> 6<script> 7if (typeof jQuery != "undefined") { 8 $('.users').each(function(index, user) { 9 console.log($(user).text()); 10 }); 11} 12</script>

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

defghi1977

2017/11/30 00:30

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

2017/11/30 00:32 編集

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

2017/11/30 00:36

多分defer属性がついている
yambejp

2017/11/30 00:37

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

回答4

0

以下は推測です.


おそらく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を使えることになります.

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

JavaScript

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

投稿2017/11/30 00:57

編集2017/11/30 02:05
defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2017/11/30 01:14

$で遅らせるのでは、その$が揃う前に「$(function(){...})」のコードが読まれてしまう以上、タイミングが良くないと間に合いません。 jQueryをdeferで読み込むこと自体、(jQueryをサブにしか使わないシチュエーションなら話は別ですが)かなり使いにくいとは思います。
defghi1977

2017/11/30 01:59

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

0

ベストアンサー

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

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

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

javascript

1// <script>内の想定 2(function main(){ 3 if(!window.$) { 4 setTimeout(main, 50); 5 return; 6 } 7 // ここまで来たときには確実に$がある 8 $(function(){ 9 // 後略 10 }); 11})(); 12

投稿2017/11/30 01:24

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

preload.js

javascript

1var $ = require('js/jquery-...min.js').$; 2 3$( ... ) // DOM構築前に何かするならここに(できることあるのかな...) 4 5$(function () { 6 // DOM構築後の処理はこちらに 7 if (typeof jQuery != "undefined") { 8 $('.users').each(function(index, user) { 9 console.log($(user).text()); 10 }); 11 } 12});

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

HTML

1... 2<script type="text/javascript" defer src="js/build.js"></script> 3<script type="text/javascript" defer src="js/heavy1.js"></script> 4<script type="text/javascript" defer src="js/heavy2.js"></script> 5...

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

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

投稿2017/11/30 01:33

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

<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 00:41

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問