プロが教える店舗&オフィスのセキュリティ対策術

hoge.htmlに
-----------------------------------------------
<script type="text/javascript" src="piyo.js"></script>
-----------------------------------------------
を記述してpiyo.jsを読み込ませました。

この状況で、piyo.js内でfuga.jsを読み込むにはどのような記述をすればよいでしょうか?

A 回答 (6件)

piyo.js内でfuga.jsで実装したモノを利用したいといういことでしょうか。


それなら
<script type="text/javascript" src="fuga.js"></script>
<script type="text/javascript" src="piyo.js"></script>
のように、piyo.jsの前に読み込ませるのが一般的です。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。

すみません、ちょっと質問文を省略しすぎてしまいました。

hoge.htmlには
-----------------------------------------------
<script type="text/javascript" src="piyo.js"></script>
-----------------------------------------------
の1文のみを表記し、
piyo.js内でfuga.jsを読み込みたい(PHPのincludeみたいな感じで)ということです。
さらに付け加えると、実際はfuga.js以外にも3つほどpiyo.js内で読み込ませたいjsファイルがあります。


また、
-----------------------------------------------
document.write("<script type='text/javascript' src='fuga.js'></script>");
-----------------------------------------------
をpiyo.js内に表記し、無理やり読み込ませてみたのですが、fuga.js内の変数や関数がうまく読み出せませんでした。


何か良い手立てはないものでしょうか?
ご教授お願いいたします。

お礼日時:2011/01/24 00:07

取り早いのは LOHAさんの回答。

ビギナーでも簡単に実現できます。
[boot.js]
--------
document.write(<SCRIPT要素>); // fuga.js を読む ( piyo.js で参照される変数があるので事前に )
document.write(<SCRIPT要素>); // hoge3.js 〃
document.write(<SCRIPT要素>); // hoge4.js 〃
document.write(<SCRIPT要素>); // piyo.js 〃(この中で document.write(<SCRIPT要素>)はNG )
--------

「fuga.js内の変数や関数がうまく読み出せない」のは、JavaScriptのオブジェクトが有効になるタイミングの問題です。JavaScriptでは使い回ししたいコードはとにかく先に読み込みを完了させて、メモリ上で有効にしておくのがポイント。
もし、「PHP のinclude のように」という言葉が、コード内の任意の場所で利用可能な特徴を指しているのであれば、「JavaScriptではやらないほうがいい。必ず先読みするのが大事」という事を理解してください。


理由は、JavaScriptが「オブジェクト汚染」という言葉もある言語だからです。
スタンダードな言葉としては存在しませんが、JSアプリケーションは「JSオブジェクトジャック」によって書き換えられる危険と常に隣り合わせです。
コード内の任意の場所で読み込む具体的な方法は得られないと思います。

一応、途中読み込みのアプローチは2つ
1) document.write() を使う。
2) XMLHttpRequest の responseText を eval()

できあがった関数を外部JSローダ関数としたとき、

いずれの方法で仕上がったとしても、以下の要件を満たす必要があります。
- タイミング制御
- 外部JSローダ関数に対するアクセス制御
    • good
    • 1
この回答へのお礼

回答ありがとうございます。

まさしくおっしゃる通り、コード内の任意の場所で利用可能な特徴があると思ってました。
わざわざその理由までご説明いただいて、とても勉強になりました。


ちなみに、
boot.jsにdocument.write(<SCRIPT要素>)を列挙する方法を試してはみたのですが、
やはりfuga.js内の関数等がうまく読み出せません。
fuga.jsの読み込み時間が結構長いので、おそらくそれが原因ではないかと思ってはいるのですが・・・



となると、私の場合は

2) XMLHttpRequest の responseText を eval()

で行なった方が良いということなのでしょうか?


なにぶんAjaxはまったくの初めてでよく分からないのですが、色々調べてみた感じ、
この 2) の指し示す処理は、fuga.jsが完全に読み込まれたことを確認してから、以降の処理をするというプログラムを組む、ということでしょうか?


いろいろ試行錯誤しましたが、結局うまく動いてくれず難儀しています。
不躾で申し訳ないのですが、もし可能でしたら、例文をご掲示いただけませんでしょうか。
よろしくお願いいたします。

お礼日時:2011/01/24 22:01

>fuga.jsの読み込み時間が結構長いので、おそらくそれが原因ではないかと思ってはいるのですが・・・


それが原因で間違いないと思います。

>2) XMLHttpRequest の responseText を eval()
>で行なった方が良いということなのでしょうか?
可能ですが、ロードしたいJSファイルは同一ドメイン内に限定されます。
なのでCDNを利用している場合などはアウトです。

他には、setIntervalやsetTimeoutをつかって無理やりロードが完了するまで待つ方法、JSONPライクにする方法、普通にイベントを使う方法、などがあるようです。

下記のURLにかなり詳しく書かれているので、じっくりご参照ください。

http://d.hatena.ne.jp/os0x/20080827/1219815828
http://blog.37to.net/2008/08/script/
    • good
    • 0
この回答へのお礼

とても有意義なページですね!
ありがとうございます!
2日間かけてじっくり参照させていただきました。


1つ目のリンク先を上から順番に見ていったところ、
ページ下部にあった以下の関数が「piyo.js内でfuga.jsを読み出す」という用途に合致していそうだ、という結論に達しました。
------------------------------------------------
function JavaScriptLoader(src, callback){
var sc = document.createElement('script');
   ・
   ・
   ・
------------------------------------------------



しかし、実力不足のせいで思うように解析ができません。


<script type="text/javascript" src="fuga.js">を実行させて、
それが完了しているのかロード中なのかを判定している、という処理をしているのだと思うのですが、
いかんせん
------------------------------------------------
if (sc.readyState == 'complete') callback(sc.readyState);
if (sc.readyState == 'loaded') callback(sc.readyState);
------------------------------------------------
のcallbackの意味がまったく分かりません。
関数の引数であるcallbackとどう繋がっているのでしょうか???
callbackにはあらかじめ何を渡しておけば良いのでしょうか???


何度もお聞きして心苦しいのですが、10時間以上かけて調べてもこれくらいしか分からない実力しか持ち合わせておらず、藁にもすがる思いです。

どうかご教授よろしくお願いいたします。

お礼日時:2011/01/26 22:09

LOHA さんの紹介する2つめのリンクが簡単に目的の動作を満たすと思います。



リンク先のページに記述されたサンプルを参考に、

new JSLoder().next('fuga.js','hoge2.js','hoge3.js', 'piyo.js').start();

あるいは、

new JSLoder().next('fuga.js').next('hoge2.js')
.next('hoge3.js').next('piyo.js').start();

といった感じでしょうか。

― おんぶに抱っこな回答で申し訳ありません。


私が回答した「ローダ関数へのアクセス制御」が必要になるケースは、ページをリロードせずに画面遷移するJSアプリケーションに限られます。

こうしたJSアプリでは画面遷移後にローダが再実行されるとマズイとか、メモリ解放しないとダメとか、質問とはかけ離れたテーマになるので、この辺りで回答を打ち切らせていただきます。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

2つめのリンクからJSLoderをダウンロードして試してみました。
しかし、これはあらかじめjsloader.jsを読み込んでおかなければならず、piyo.js内では
------------------------------------------------
new JSLoder().next('fuga.js','hoge2.js','hoge3.js', 'piyo.js').start();
------------------------------------------------
を実行できませんでした。


何か実行させる良い方法がありますでしょうか?

お礼日時:2011/01/26 22:19

>function JavaScriptLoader(src, callback){


>のcallbackの意味がまったく分かりません。
>関数の引数であるcallbackとどう繋がっているのでしょうか???
>callbackにはあらかじめ何を渡しておけば良いのでしょうか???

例えば、a.js、b.jsの順で読み込ませたい場合、a.jsを読み込みが完了したことを確認してから、b.jsを読み込ませることになります。
こういった(非同期の)処理の場合は、a.jsが読み込み終わったときに、ある関数を呼び出すようにする、という定石があります。その「ある関数」内でb.jsを読み込ませればよい、という仕組みです。

参考サイトに掲載されていたJavaScriptLoader関数はそのような仕組みでできており、ロード完了時に呼び出される「ある関数」が第2引数であるcallbackです。
#このような関数のことを、コールバック関数と呼びます。それが引数callbackの名前の由来です。
http://e-words.jp/w/E382B3E383BCE383ABE38390E383 …

>if (sc.readyState == 'complete') callback(sc.readyState);
>if (sc.readyState == 'loaded') callback(sc.readyState);

このような内部構造はとりあえず理解しなくても大丈夫だと思うので、簡単な使い方だけ書いておきます。

JavaScriptLoader("a.js", function(state) {
 // a.js内の関数などを利用する処理
 JavaScriptLoader("b.js", function(state) {
  // a.js, b.js内の関数などを利用する処理
 });
});

#callback関数である無名関数の第一引数にstateを指定していますが、これはなくてもOKです。

>2つめのリンクからJSLoderをダウンロードして試してみました。
>しかし、これはあらかじめjsloader.jsを読み込んでおかなければならず、piyo.js内では...

jsloader.jsの中身をpiyo.js内にコピーしてしまえば良い(ライセンスには気をつけましょう)、といえばそれまでなのですが、結構量あるのでJavaScriptLoaderの方が手軽かもしれませんね。

#両方を組み合わせる手もありですが、それはそれで冗長かな。

以上です。
解決されることをお祈りします。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

できました!!

ずいぶん時間がかかってしまいましたが、
JavaScriptLoaderがどういう処理を行なっているのか、
なぜ教えていただいた方法で呼び出すことができるのか、
も含めてすべて解決いたしました!

親切丁寧に教えていただいてほんと感謝感謝です!

お礼日時:2011/01/30 12:33

new JSLoder().next('fuga.js','hoge2.js','hoge3.js', 'piyo.js').start();



が利用できない原因はSCRIPT要素を使うため、DOM要素を利用可能になったタイミング以降で実行されるような遅延処理が必要です。

たとえば、
window.onload = function(){ /* ここに書く必要がある */ }

あと、AJAX + eval を使ったローダについては、
http://blog.livedoor.jp/aki_mana/archives/233349 …
にアップしてみました。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

今回はJavaScriptLoaderという前述の関数を使わせてもらいましたが、アップいただいたローダはまた次の機会に使わせていただきます。

本当にありがとうございました!

お礼日時:2011/01/30 12:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!