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

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

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

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

Q&A

解決済

2回答

2336閲覧

JavaScript の読み込みについて教えて下さい

pectin

総合スコア95

JavaScript

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

3グッド

1クリップ

投稿2019/02/19 12:13

JavaScript を <script> タグを使って読み込む方法と、document.head.appendChild() を使って読み込む方法の違いが知りたいです

既存の JavaScript 読み込みが document.write('http://poi.jp/javascript.js') と読み込んでいます。

調べると document.write() は非推奨とのことなので、代替手段で修正を考えています。

そこで気になったのですが、以下の認識があっているかどうかがわからないため、ご存知の方がいらっしゃいましたら、教えていただけると助かります。

知りたいこと その1)

<head> <script src="http://poi.jp/a.js"> <script src="http://poi.jp/b.js"> <script src="http://poi.jp/c.js"> </head>

c.js の中で a.js または b.js の関数を利用したいが、この場合は上から順番に解釈されるので、c.js が a.js または b.js の関数を呼び出そうとした時は、a.js と b.js の読み込み完了が保証されているので c.js から a.js または b.js の関数を呼び出すことができる

知りたいこと その2)

<head> <script src="http://poi.jp/a.js"> <script src="http://poi.jp/c.js"> </head>

a.js の中身
var b_js = document.createElement('script');
b_js.src = 'http://poi.jp/b.js';
document.head.appendChild(b_js);

この場合も c.js の中で a.js または b.js の関数を利用したいが、この場合は a.js を読み込む途中で b.js を読み込み、c.js が a.js または b.js の関数を呼び出そうとした時は、a.js と b.js の読み込み完了が保証されているので c.js から a.js または b.js の関数を呼び出すことができる

と解釈していますが、どちらも正しい解釈でしょうか?

ちなみに document.write() が非推奨とのことですが、具体的な不具合(または 不都合)をご存知でしたら併せて教えていただけると助かります。

解釈について、不足している点がございましたら、お手数ですがその旨をお申し付け下さい。

よろしくお願いします。

Lhankor_Mhy, x_x, bwz61366👍を押しています

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

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

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

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

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

x_x

2019/02/20 01:45 編集

document.write('http://poi.jp/javascript.js') としたところでhttp://poi.jp/javascript.jsという文字列が書き込まれるだけですが、何か勘違いしているのでは?
pectin

2019/02/20 08:02

ご指摘ありがとうございました。 ご指摘の通り document.write('<script src="http://poi.jp/javascript.js">'); が正解です。
guest

回答2

0

ベストアンサー

その1) は正しいと思いますが、その2) は想定どおりに動かないと思います。スクリプトはおそらくACBの順で実行されることがあると思います。

(document.createElement() を使用して) 動的に挿入されたスクリプトは、既定で非同期に読み込まれますので、同期的に読み込まれる (すなわち挿入順に読み込まれる) スクリプトには async="false" を設定してください。

<script>: スクリプト要素 - HTML: HyperText Markup Language | MDN

document.write のことをすっかり忘れていたので追記

閉じられた (読み込み済みの) 文書で document.write を呼び出すと、自動的に document.open が呼び出され、文書はクリアされます。

document.write および document.writeln は、 XHTML 文書では動作しません

Document.write() - Web API | MDN

などなど。

投稿2019/02/19 12:38

編集2019/02/19 12:47
Lhankor_Mhy

総合スコア35865

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

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

Lhankor_Mhy

2019/02/19 13:13

開発者ツールで確認してみましたが、b.jsを読むのがかなり遅いです。私見ですが、動的なスクリプトの挿入は非同期なだけではなくて、HTML文書の解析を待っているような気がしました。
pectin

2019/02/20 08:01

ご回答ありがとうございました。 MDN の説明をみてイメージがつきました。
pectin

2019/02/22 01:23

Lhankor_Mhy さん ご回答ありがとうございました。 そうしますと、appendChild() を使う方式の場合は、async = false をつけても非同期で読み込まれるため、その1のような順番にする方法がないということで解釈は合っていますでしょうか? ----- (document.createElement() を使用して) 動的に挿入されたスクリプトは、既定で非同期に読み込まれますので、同期的に読み込まれる (すなわち挿入順に読み込まれる) スクリプトには async="false" を設定してください。 ----- と記載があるので大丈夫かと思ったのですが、そうではないということですね... 最悪別の改修方法を考案する必要がありそうだということも視野に入れるようにします。
Lhankor_Mhy

2019/02/22 01:35

現状は、私の認識と質問者様のそのご理解は同じであると思いますが、他に方法があるか否かについては、仕様にたどり着いていないので確証がありません。
pectin

2019/02/23 01:50

ありがとうございました。 この実装方法で稼働に支障をきたすようであれば、HTML 側に静的に <script> タグを使うなど同期が取れる形に代替しようと思います。
guest

0

1,2共に合っています。

※defer,async属性の例外はあります。
https://teratail.com/questions/124923

Re: pectin さん

投稿2019/02/19 12:17

編集2019/02/19 12:28
think49

総合スコア18156

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

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

think49

2019/02/19 12:44

一応補足しますが、2.を正しいとしたのは、a,bの実行順に触れられていなかったからです。 b.jsからaの関数を呼び出すには、a.jsの関数定義が終わった後(全てが同期的に動くコードならa.jsの最終行)に b.js を挿入する必要があります。
x_x

2019/02/20 02:11 編集

問題となるのはcからbの参照では?
think49

2019/02/20 03:45

私の理解では、defer,async属性が付与されていない場合において、cからbは問題ないと認識していましたが、appendChildは同期処理ではなかったでしょうか。
x_x

2019/02/20 04:06

それは Lhankor_Mhy さんの回答の通りで、実際にブラウザで追試験してみても c から b を参照できないようでした。
pectin

2019/02/20 08:00

think49 さん ご回答ありがとうございました。 b.js から a の関数を呼び出す場合は、a.js の最終行に b.js を appendChile() で挿入するということですね。 定義の順番からすると最後であれば a.js の定義が全て終わっている状態が保証されているというイメージができました。 ありがとうございます。
pectin

2019/02/20 08:01

x_x さん ご回答ありがとうございました。 そうしますと、ACB の順番で読み込まれるため C→Bの参照ができないというのが正しいでしょうか? <script>タグを使った場合は定義した順の ABC で、appendChild() で定義した場合も同じようにしたい場合は、createElement().async = false を使えばよいと思ったのですが、それは間違いということでしょうか?
Lhankor_Mhy

2019/02/20 08:43

横からすみません。 > appendChild() で定義した場合も同じようにしたい場合は、createElement().async = false を使えばよいと思ったのですが、 私もそう思ったのですが、私の回答のコメントにも書いたとおり、どうも上手くいかないようです。 回答で提示したMDNのページのdefer属性のところに、気になる記述があったため、少し仕様などをあさってみたのですが、上手く説明できる文書にたどり着けませんでした。 なので、仕様の問題か、実装の問題なのか、区別できていません。
pectin

2019/02/20 20:28

Lhankor_Mhy さん ご回答ありがとうございました。 そうしますと、appendChild() を使う方式の場合は、async = false をつけても非同期で読み込まれるため、その1のような順番にする方法がないということで解釈は合っていますでしょうか? ----- (document.createElement() を使用して) 動的に挿入されたスクリプトは、既定で非同期に読み込まれますので、同期的に読み込まれる (すなわち挿入順に読み込まれる) スクリプトには async="false" を設定してください。 ----- と記載があるので大丈夫かと思ったのですが、そうではないということですね... 最悪別の改修方法を考案する必要がありそうだということも視野に入れるようにします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問