こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

外部jsファイルから本体の関数を呼ぶには

外部jsファイルを読み込んで処理する以下の1の例のようなプログラムがありました。
外部ファイルを読み込む前に処理をスタートしているからか、
get()が見つからないとエラーがでる場合がありました。

1の例)
■index.html
window.onload = function loaded(){
get('a');
}

■outer.js
function get(a){
alert(a);
}

そこで2の例のように外部ファイルから本体の関数を呼ぶようにしましたが、
これは毎回オブジェクトが見つからないとエラーがでます。

2の例)
■index.html
function loaded(){
get('a');
}

■outer.js
function get(a){
alert(a);
}
window.onload = loaded();


そこで質問なのですが、1の例からエラーが無くなる様に外部ファイルを完全に読み込んだのを判断して処理を始めるというのはどういう風に書けばいいのでしょうか?

もう一つ、2の例のように外部jsファイルから本体の関数を呼ぶにはどう書けばいいのでしょうか?(例では簡単に書いていますが実際は複雑で、本体をキックしたいのです)

ぜひアドバイスを頂ければと思っております。宜しくお願い致します。

投稿日時 - 2011-06-06 07:39:26

QNo.6789615

困ってます

質問者が選んだベストアンサー

[ANo.3] の補足に対する回答ね。


「外部ファイルも読み込んでからなのでしょうか?」
うのみにしないことは、いいことだね!

| At this point, all of the objects in the document are in the DOM

この文をよく読んでほしいんだけど、
『この時点で、文書の中の全ての objects は、DOM の中にある。』
とかかれてるよね。この objects が重要なんだけ、これは object 要素を表しているわけじゃないよ。
要素も属性も、もろもろあわせて全部といういみなんだ。

たとえば、下のような HTML 文書片が書かれた HTML 文書があるとするよ、
<p>あああ<script type="text/javascript" src="http://another.domain.com/outer.js"></script>いいい</p>

より汎用的に説明するために outer.js は、この HTML 文書とは別のドメインにするね。
ウェブブラウザが、この HTML 文書を読み終えて、outer.js を読み込む前の状態を考えてみよう!

このとき、
『この時点で、文書の中の全ての objects は、DOM の中にある。』
は、なりたつかな?

outer.js に次の行がかかれているとしたら、わかりやすいかな?
document.write("<span>ううう</span>");

投稿日時 - 2011-06-06 14:07:56

補足

ご回答ありがとうございます。
時間が無く色いろ試してから返信しようと思いましたが、この点だけ指摘させてください。

それなら in the documents の複数形になりませんでしょうか?

時間を見つけてどこまで読み込むのか調べて報告はしたいと思っています。

投稿日時 - 2011-06-07 22:24:26

お礼

ザックリ調べまして結局こうすることにしました。間違っているかも知れませんが対処療法はできると思います。
■index.html
function loaded(){
get('a');
}
■outer.js
function get(a){
alert(a);
}
window.onload = function(){
loaded();
}

■window.onloadの動作について
本体への記入だと本体ファイルが読み込まれたら実行される
外部ファイルへの記入だと本体と外部ファイルが読み込まれたら実行される
※外部ファイルが見つからない場合に永遠に待ってしまうから

■根拠
実行されるときに、まだ外部ファイルが読み込まれておらず、 display_date2 が未定義になる可能性があります
http://homepage3.nifty.com/aya_js/js2/js201.htm

onloadを記述したファイルはひとつしか読み込めません
例えば2つのファイルにwindow.onload=sample;を記述した場合どちらかひとつのonloadイベントしか発生しません(最後のもの)
http://www7b.biglobe.ne.jp/~hmkuukan/hmkiho/fyomi.html

onloadを一つ+jQueryのreadyメソッドは複数でも可
http://tam-tam.co.jp/tipsnote/javascript/post658.html

複数のonloadイベントはaddEventする
http://lets-customize.seesaa.net/article/101533572.html

投稿日時 - 2011-06-13 02:37:47

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

論理的な実例を示した。それでも、疑問が続くなら、その論理的な実例の意味を正しく理解できていないか、拒絶してるか、はじめから論点がずれていて、じつは、話が噛み合っていなかったかだね。あとは、質問者さんの、きもちしだいかな?

「負荷などを掛け外部ファイルの読 み込みに問題のある環境を作りだ さないと(外 部ファイルを待つという)検証は できないのではないでしょうか?」
については、[ANo.3] で答えてるから省略。

結構楽しかったし、[ANo.3] の知識を深めるきっかけになったよ。ありがとう!

投稿日時 - 2011-06-26 00:42:03

補足

ANo.6のonload.htmだけを作り、outer.jsは作らずに実行すれば、onloadedと表示されます。

つまり言いたいことは、外部ファイルの読み込みを待たずに実行されるのです。

投稿日時 - 2011-06-27 01:53:20

ANo.6

http://homepage3.nifty.com/aya_js/js2/js201.htm
更新日時: 2004年 8月 11日 水曜日 7:11:30

最新の情報が書かれていないおそれがあるからきをつけて!



言葉だけで攻略しようとおもったけど、なかなかのやり手なので、ちょっと日和る。
とりあえず、実行してみればわかるとおもうよ。
"onloaded" と "outer.js" どっちがさきに表示される?


[onload.htm]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>実例出したほうがはやいじゃないか!</title>
<script type="text/javascript">
window.onload = function () { alert('onloaded'); };
</script>
<script type="text/javascript" src="outer.js"></script>
</head>
<body>
<h1>実例出したほうがはやいじゃないか!</h1>
</body>
</html>


[outer.js]
alert('outer.js');

投稿日時 - 2011-06-13 14:41:40

補足

ありがとうございます。
毎回outer.jsが表示されました。

外部ファイルを待つと解釈したいのですが、本体ファイルだけを待っているとも取れますね。
負荷などを掛け外部ファイルの読み込みに問題のある環境を作りださないと(外部ファイルを待つという)検証はできないのではないでしょうか?

投稿日時 - 2011-06-25 21:12:44

ANo.4

#2です。

>window.onload = loaded();
>は関数loaded()を実行しようとしていました。
そのままだと、パース時をloadedを実行して戻り値をwindow.onloadとしてセットすることになります。
したがって、その時点でloadedが定義済みでなければエラーになりますし、通常このような場合には
 function loaded(){
  return function(){ get('a'); };
 }
のように、関数オブジェクトを返すようになっているのが一般的なはずです。
(window.onloadにセットするので)

ご質問で例示のものはそのようになっていないので、#2でも書きましたが、
 window.onload = loaded;
としたかったのではないかと…
こちらだと、loadedは読込み時に実行されずにwindow.onloadにセットされるだけで、onload(読込み終了時)に始めて実行されるという違いがありますが、そのあたりを混同なさっていませんか?

投稿日時 - 2011-06-06 13:51:59

お礼

ご回答ありがとうございます。
ご指摘の通り window.onload = loaded; をしたかったのです。
動作しました!

投稿日時 - 2011-06-13 02:30:44

ANo.3

「外部ファイルを読み込む前に処理をスタートしているからか、get()が見つからないとエラーがでる場合がありました。」

ということはなくて、

window.onload のイベントは、外部の JavaScript も含めて、画像だとか、CSS ファイルだとか、全部よみこまれて、ウェブブラウザに解釈されて始めて、発生するものだから、静的(※1)なものなら何処に書いていても、必ず、window.onload で指定した関数がよばれるよ。(※2)

(※1) document.createElement('src') とか xmlHttpRequest で JavaScript ファイルを後から動的に読み込ませないときのこと


(※2)↓このことが書いてあるページ

https://developer.mozilla.org/en/DOM/window.onload
| Notes
|
| The load event fires at the end of the document loading process.
| At this point, all of the objects in the document are in the DOM,
| and all the images and sub-frames have finished loading.

http://msdn.microsoft.com/en-us/library/ms535873%28v=vs.85%29.aspx
| Remarks
|
| The client loads applications, embedded objects, and images
| as soon as it encounters the applet, embed, and img objects
| during parsing. Consequently, the onload event
| for these objects occurs before the client parses
| any subsequent objects. To ensure that an event handler receives
| the onload event for these objects, place the script object that
| defines the event handler before the object and use
| the onload attribute in the object to set the handler.

あまりないとおもうけど、今回のようなケースで
「get()が見つからないとエラーが」
でたり、出なかったりするのは、outer.js ファイルが一時的に読み込めなくてタイムアウトになったときぐらいかな?


そうゆうわけだから、たぶん、outer.js をエディタで編集しながら、確認してて、JavaScript の構文が間違ってるときに、エラーがでて、直ったときに正常に表示されてるだけなんじゃないかな?とおもった。

投稿日時 - 2011-06-06 12:36:27

補足

ご回答ありがとうございます。
外部ファイルも読み込んでからなのでしょうか?そうすると何故エラーになるのか不明です。。エディタで編集しながら確認した訳ではありませんし。。サーバーが不安定である可能性はありますが。。

mozillaをよく読むと、画像とサブフレームは読み込まれるとは書いていますが外部ファイルには言及してませんね。onloadの範囲についてもう少し調べてみたいと思います。

投稿日時 - 2011-06-06 13:07:58

ANo.2

ご質問の意味が判りかねますが…

>外部ファイルを読み込む前に処理をスタートしているからか、
ご質問通りの順で処理をしているのなら、当然エラーになるのではないでしょうか。
基本的に、ソースの読込み順に逐次処理されるはずですので、記述の順序さえ間違えなければ問題は起きないと思いますが。

ご提示の例の場合
 window.onload = loaded();
って、意図の通りでしょうか?(window.onload = loaded; のタイポ?)

>毎回オブジェクトが見つからないとエラーがでます。
単純に、外部ファイルの読込みが先なので、loadedが未定義ということではないのですか?


ご質問とは関係ありませんが…
外部ファイルと本体のスクリプトの使い分けをどのようになさっているのか不明ですが、外部ファイルは共通の汎用処理や定型的な処理群で構成されているのではないかと想像します。一方で、本体内のスクリプトはそのファイル個別の処理や、パラメータをセットして外部ファイル内の関数を呼び出すなどの処理になっているのではないでしょか?

>外部jsファイルから本体の関数を呼ぶにはどう書けばいいのでしょうか
前述のように、記述の順序さえ気をつければよいと思いますが、外部と内部が上のような書き分けになっていると仮定すれば、そもそも外部の処理から直接本体を呼ぶ必要性はなくなるはずと思いますが…(外部ファイルの内容の一般性が損なわれるので)
仮に、同じ意味の処理がページによって個別の処理をせざるを得ないた事情があって本体内に記述されていたとしても、直接呼び出さずに、セットアップ時に本体側からその処理関数を引数にして渡すようにしておくなどで、一般性維持することが可能だと思われます。
どうしても直接呼び出す必然性があるのなら、それを分離することが不自然なので、全体をパッケージにして外部ファイルにしてしまった方がよいのではないでしょうか?

投稿日時 - 2011-06-06 11:03:37

補足

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

window.onload = loaded();
は関数loaded()を実行しようとしていました。構文は自信がありません。。

ファイルの使い分けですが、本来なら1の例の通りにしたいのですがエラーが出てしまったものですから、いい方法がないかと思っていました。

1の例でも特に問題は無さそうですね。エラー原因が何かもう少し考える必要がありそうです。。

投稿日時 - 2011-06-06 13:14:28

ANo.1

なにをしたいのかいまいち理解できませんが
すなおに、外部jsの中でwindow.onloadすればよいのでは?

蛇足ですがjavascriptの文法がかなりおかしいのでもうすこし
注意深くした方がよろしいかと

投稿日時 - 2011-06-06 09:54:28

補足

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

>外部jsの中でwindow.onloadすればよいのでは?
文法は自信がありませんので、勉強して試してみたいと思います。

投稿日時 - 2011-06-06 13:16:01

あなたにオススメの質問