Internet Explorer の右クリックメニューに登録するスクリプトを作っています。
たとえば、いま表示しているページのURLを表示する場合、
<script type="text/javascript">
var parentWindow = window.menuArguments;
var URL = parentWindow.document.URL;
window.onload = function() {
kansuu(URL);
};
kansuu = function(url) {
alert(url);
}
</script>
↑は動きます。
また、
var parentWindow = window.menuArguments;
var URL = parentWindow.document.URL;
window.onload = kansuu(URL);
function kansuu(url) {
alert(url);
}
↑も動きます。
ところが、
var parentWindow = window.menuArguments;
var URL = parentWindow.document.URL;
window.onload = kansuu(URL);
kansuu = function(url) {
alert(url);
}
は動きません。
なぜでしょうか?
理由を教えていただけると嬉しいです。
よろしくお願いします。
No.5ベストアンサー
- 回答日時:
> よく「onload は DOM 木を全て読み込んだ後で実行される」と聞きますが、違うのでしょうか?
これ自体は正しいです。
しかし、window.onload = kansuu; と書いたときの話で、window.onload = kansuu(URL); と書いたときに
kansuu(URL) の実行を DOM 木の読み込みが終わるまで待ってくれる訳ではありません。
以下の例を実行してみてください。
function func() {
alert("関数が呼ばれました。");
}
var f;
alert("f = func;");
f = func;
alert("f = " + f);
alert("f();");
f();
alert("f = func()");
f = func();
alert("f = " + f);
alert("f();");
f();
// f には何も入っていないので、エラーが発生します。
// (window.onload は何も入っていないときは実行されないので window.onload に何も入っていないときには
// 特にエラーは発生しません。
これを実行すると、
1. 「f = func;」と表示される
2. f = func の行では何も表示されない (func() は実行されていない)
3. f = function () { ... } と表示される (関数が代入されている)
4. f(); を実行すると、f = func; で代入した func(); が実行され、「関数が呼ばれました」と表示される
5. 「f = func();」と表示される
6. f = func(); の行で「関数が呼ばれました」と表示される (この時点で func() は実行されている)
7. 「f = undefined」(ここでは、 fには何も入っていない、と思ってください)と表示される
8. f(); の行では f に何も入っておらず、何も表示されない
(func()は実行されていない。ブラウザによってはエラーが表示されるかもしれません)
となります。これと同様に
・window.onload = kansuu; と書けば DOM 木が読み込まれた時点で kansuu が実行される
・window.onload = kansuu(URL); と書けば、この行で kansuu(URL); を実行し、
DOM 木が読み込まれた時点では何も実行されません。
> onload の時点では、
> kansuu = function (url){} の代入は行われていませんが、
> なぜ動くのでしょうか?
kansuu(URL); を実行しようとした時点では kansuu に値が入っているので、問題ありません。
1. window.onload = function () { ... }; で window.onload に関数(「関数1」と書くこととします)が代入される。
2. kansuu = function (url) { ... }; で kansuu に関数(「関数2」と書くこととします)が代入される。
3. DOM 木の読み込みが完了する。
4. ブラウザが window.onload に指定された関数(関数1)を実行する
5. 関数1で kansuu(URL); を実行しようとしたときには kansuu には関数2が代入されているので、
関数2を実行する。
6. 関数2でURLが表示される。
window.onload = function () {
alert(num);
};
num = 123;
としたとき、num = 123; が実行されて num に 123 が入ったあとに window.onload が実行されて
「123」と表示されるのと同じです。
No.3
- 回答日時:
よこからですが…
ANo1様がすでに回答なさっている通りなのですが、よく理解なさっていないようなので…
>onload は DOM 木を全て読み込んだ後で実行される
その通りですが、質問者様の解釈に一部誤解があるようです。
細かく言うと、「onload時にonload eventが発生し、event処理の関数が(設定されていれば)実行される」ということになります。
一方で、ご提示のスクリプトが実行されるのはロード中で、上記のイベント処理関数を定義するところで問題が生じているということになるかと思います。
以下の違いをANo1様の説明と照合しながら確認してみてください。
簡単な説明を付けましたが、ほとんどがロード中に実行されるスクリプトの動作説明です。(ロード後ではありません)
<例1>
window.onload = function(){ kansu("test"); };
alert(window.onload);
function kansu(word){ alert(word); };
1行目でonloadのハンドラ(関数)としてfunction kannsuが設定される。
2行目では「function(){ kansu("test"); }」と表示されるはず。
(onload時にkansuが実行されます。)
<例2>
window.onload = kansu("test");
alert(window.onload);
function kansu(word){ alert(word); };
1行目でkansuが実行され、「test」が表示される。(返り値はundefinedなのでonloadのハンドラとしては何も定義されない)
2行目の処理はブラウザによって異なるようです。nullやundefinedが表示されたり、1行目でエラー扱いとなって2行目以降は動作しない場合などいろいろあるようです。
(onload時には、設定がないので何もしません。)
<例3>
window.onload = kansu("test");
var kansu = function(word){ alert(word); };
1行目でkansuを実行しようとするが、未定義なのでエラーとなる。
(onload時には、設定がないので何もしません。)
<例4>
var kansu = function(){ alert("Hellow"); };
window.onload = kansu;
alert(window.onload);
2行目でイベントハンドラとしてkansuが設定される。
3行目では「function(){ alert("Hellow"); }」と表示される。
(onload時には、kansuが実行され「Hellow」と表示される。)
No.2
- 回答日時:
javascriptの原則は
・function宣言された関数は先に評価される
・スクリプトは上から順に評価される
なので
kansuu=function(){}
を書く前にkansuuを参照しようとしても無理
たとえば
<script>
kansuu(1);
kansuu = function(num) {
alert(num);
}
</script>
はNGだけど
<script>
kansuu = function(num) {
alert(num);
}
kansuu(2);
</script>
ならいける
#1さんの指摘にもあるとおり
window.onload = kansuu(URL);
はありえない
<script>
window.onload=function(){kansuu(3)};
kansuu(4);
function kansuu(num) {
alert(num);
}
</script>
と
<script>
window.onload=kansuu(3);
kansuu(4);
function kansuu(num) {
alert(num);
}
</script>
の実行される順番がなぜちがうか理解した方がよいでしょう
前者はonload時に実行していますが
後者は、単純に上から順番にスクリプトを実行しているだけなので
onloadにはkansuu(3)を実行した結果が設定され、実際にonload時には
なにもされていない
No.1
- 回答日時:
まず、以下の点にご注意ください。
・function kansuu() { ... } と直接書くと全体で kansuu の名前は有効になります。
・kansuu = function () { ... }; とした場合は、代入した後でしか関数は利用できません。
hoge = 1; という文があったとして、hoge = 1; とする前に hoge の内容を表示しても 1 ではないのと同じことです。
ということで、上記のスクリプトはそれぞれ
■ window.onload = function () { ... }; としたとき
window.onload で指定した関数が実行されるときには、
kansuu = function () { ... }; を通過した後なので、
kansuu の内容が実行されます。
■ function kansu() {} とした場合
kansuu はどこからでも参照できますので、window.onload = kansuu(URL); は有効です。
ですが、予想した通りに動いているとは思えません。
window.onload = kansuu(URL); とした場合、以下のように動作します。
1. window.onload の行に来た時点で、kansuu(URL) を実行します。 (まだ読み込みは完了していない)
2. kansuu は戻り値を返していないので undefined が返却される
3. window.onload のタイミングでは何もしない
ということで、読み込まれる前に kansuu は実行されますが、問題はないですか?
window.onload = kansuu; と window.onload = kansuu(URL); では
関数自体を代入するのと、関数の戻り値を代入するという違いがあります。
■ window.onload = kansuu(URL); とした場合
kansuu = function ... が代入される前に読み込んでいるので、値がありません。
foo = bar;
bar = 1;
として foo に 1 が代入されないのと同じことです。
window.onload = ... の前に kansuu = ... を持ってくれば 2 つ目と同じ振る舞いをします。
(やはり、window.onload は何もしませんが)
この回答への補足
回答ありがとうございます。
次のところがよくわかりません。
>window.onload = kansuu(URL); とした場合、以下のように動作します。
>1. window.onload の行に来た時点で、kansuu(URL) を実行します。 (まだ読み込みは完了していない)
>2. kansuu は戻り値を返していないので undefined が返却される
>3. window.onload のタイミングでは何もしない
>ということで、読み込まれる前に kansuu は実行されますが、問題はないですか?
よく「onload は DOM 木を全て読み込んだ後で実行される」と聞きますが、違うのでしょうか?
だからこそ私の挙げた1番目と2番目のスクリプトが動くのだと思っていました。
>■ window.onload = kansuu(URL); とした場合
>kansuu = function ... が代入される前に読み込んでいるので、値がありません。
とありますが、私が挙げた1番目のスクリプトでも、
onload の時点では、
kansuu = function (url){} の代入は行われていませんが、
なぜ動くのでしょうか?
すみませんが、もう少し整理して教えていただけると助かります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- オープンソース Coinmarketcap api 1 2022/05/30 15:47
- JavaScript スマフォではボタンを表示させたくない 2 2023/01/20 14:26
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
- JavaScript JAVASCRIPT 2 2022/04/15 15:10
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript 正規表現について質問です。条件に合う場合はtrueを返したい 3 2022/10/06 23:02
- JavaScript コードレビューをお願いします。 1 2022/07/16 05:38
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- JavaScript jQueryでのレスポンシブが綺麗に動かない 3 2022/06/21 11:08
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
デザイン時のVisible=Falseは実...
-
if(1){...}とはどういうことで...
-
jQuery ui Datepicker 明日以降...
-
初心者です。gulpでコンパイル...
-
jspで、javaを呼び出すときの引...
-
Excel VBA にて JavaScript の...
-
VB.netでタイマーがスタートし...
-
オーバーライドについて。
-
リクエスト結果が一瞬しか表示...
-
PowerPointで時計表示
-
javascriptで最初のところに戻...
-
CreateFile、CloseHandleの繰り...
-
VB.netの重複データ数カウント...
-
javascriptでsjisの文字列からu...
-
JSPの処理の途中で、JavaScript...
-
1つのVBAコードをすべてのコア...
-
2回目のSortメソッドが失敗~20...
-
ACCESS(VBA)の検索結果判定に...
-
jquery の書き始めについて
-
既存のwebサイトで、ローカルの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
以下のコードを実行しても、オ...
-
JSPの処理の途中で、JavaScript...
-
if(1){...}とはどういうことで...
-
1つのVBAコードをすべてのコア...
-
VBA ステータスバー DoEvents
-
〔Excel:VBA〕マクロの実行が異...
-
jQuery ui Datepicker 明日以降...
-
デザイン時のVisible=Falseは実...
-
VBA SORT Applyでエラー
-
リクエスト結果が一瞬しか表示...
-
C#でボタン名を変更しても動く
-
PowerPointで時計表示
-
innerHTMLなどの反映タイミング
-
javascriptで最初のところに戻...
-
初心者です。gulpでコンパイル...
-
onbeforeunload と aタグの hre...
-
ラベルの色がかわってくれない
-
エクセル VBA タイマー動作 の...
-
JavaScriptで、実行するたび値...
-
Excel VBA にて JavaScript の...
おすすめ情報