• ベストアンサー

JavaScriptを最後に実行するには?

JavaScriptでリンクをランダムに表示するようにしたところ、 少し表示が遅く感じるようになったため、 最後にJavaScriptを実行するようにonloadイベントを使って [外部(JavaScript)ファイル] <!-- window.onload = function onload(){ var random = Math.floor(Math.random() * 3); if(random == 0) document.write('<a href="URL1">サイト名1</a>'); else if(random == 1) document.write('<a href="URL2">サイト名2</a>'); else if(random == 2) document.write('<a href="URL3">サイト名3</a>'); }; //--> [HTMLファイル内] <script type="text/javascript" src="./フォルダ名/ファイル名.js"></script> のように書いて試しましたが、真っ白なページにこのスクリプトの内容だけが表示されてしまいます。 "window.onload = function onload{"と、最後の"};"の部分を追加するまでは普通に動いていました。 また、ページ内に、別の外部ファイルも含めて同じようなものを複数組み込みたいと思っています。 この方法でなんとか表示したいのですが、 別の方法も含め、情報をいただきたいです。 わかりにくいところがあれば補足します。 よろしくお願いします。

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.8

#6>表示させたいところに<script~></script>と書き込むと思うのです 表示させたいところに、<script~></script> を書き込むのは、 document.write を使っている場合そのようになります。 一般的には、スクリプトの位置でアクセスして使えるオブジェクトは、変わっても、書き込む位置というのは関係ありません。 #2の様にid 指定で書き込み位置を指定してやりましょう。 スクリプトを配置した位置に書き込むというのであれば 元のdocument.write による方法がいいと思います。 #6>書き込んだところに表示されずにページの最後に表示されてしまいます。 #6>この動作は正しいのでしょうか。 #6でも書いていますし、#7でも説明されていますが、 #3は、最後に追加するものです。 (body のappendChild でなくても任意のエレメントに追加したり挿入したり置き換えたりできますが、その場所は特定する必要があります)

noname#46450
質問者

お礼

回答ありがとうございました。 document.writeによる方法だと思った通りのものができないので#9の方法を使わせていただくことにしました。 使ったものも#9のところに載せておきます。 いろいろと勉強になりました。ありがとうございました。

その他の回答 (8)

  • mognol_n
  • ベストアンサー率61% (8/13)
回答No.9

#2の方法で複数表示させる方法ですが、BLUEPIXY様の書いたとおりid要素はHTML内で一度しか使わないものです。 なので複数表示させる場合は、 [JavaScript] window.onload = function (){ for (i = 0; i < 2; i++) { var random = Math.floor(Math.random() * 3); var x = document.getElementById("rlink" + i); if (random == 0) x.innerHTML = '<a href="URL1">サイト名1</a>'; else if(random == 1) x.innerHTML = '<a href="URL2">サイト名2</a>'; else if(random == 2) x.innerHTML = '<a href="URL3">サイト名3</a>'; } } [HTML] <div id="rlink0"></div> <div id="rlink1"></div> (それぞれリンクを表示したい部分に。インライン要素にしたい場合はdivでなくてspanを使用。) このように複数用意するのが一番手っ取り早いかと思います。 まだ数を増やしたければ i < 2 の部分の数を増やして、 rlink2、rlink3 というように idを変えて記述していけば簡単に増やせます。 この場合だと各リンクの内容はリンクごとにランダムになりますが、すべてのリンクを同じにしたければ var random = ~ の部分を for ループの外に出せば良いだけです。 JavaScriptの実行順序に関してですが、基本的には記述してある順に実行しますので、body内の途中に記述した場合はその位置で実行されます。 #8に書いてあるようにdocument.write等を用いる場合は、body内の表示したい位置に書くことになるでしょう。 しかしここで私やBLUEPIXY様が出している回答は、すべて関数を作成して呼び出す形を取っています。 この場合、関数は記述した位置で定義されるだけであり、実行は実際に呼び出した位置(この場合だと onload を用いているためHTMLの読み込みがすべて終わったあと)で行われます。 なので記述する位置はどこであろうと結果は変わりません。 (一般的にhead内に書かれる事が多いです)

noname#46450
質問者

お礼

回答ありがとうございました。説明、わかりやすかったです。 おかげさまで思い通りに表示させることができるようになりました。 使ったものを載せておきます。 [外部ファイル1] <!-- Event.observe(window, 'load', func1, false); function func1() { for (i = 0; i < 3; i++) { var random = Math.floor(Math.random() * 3); var x = document.getElementById("rlinka" + i); if (random == 0) x.innerHTML = '<a href="URL1">サイト名1</a>'; else if(random == 1) x.innerHTML = '<a href="URL2">サイト名2</a>'; else if(random == 2) x.innerHTML = '<a href="URL3">サイト名3</a>'; } } --//> [外部ファイル2] <!-- Event.observe(window, 'load', func2, false); function func2() { for (i = 0; i < 3; i++) { var random = Math.floor(Math.random() * 3); var x = document.getElementById("rlinkb" + i); if (random == 0) x.innerHTML = '<a href="URL1">サイト名1</a>'; else if(random == 1) x.innerHTML = '<a href="URL2">サイト名2</a>'; else if(random == 2) x.innerHTML = '<a href="URL3">サイト名3</a>'; } } --//> [HTMLファイル] <head> <script type="text/javascript" src="./prototype-1.4.0/dist/prototype.js"></script> <script type="text/javascript" src="./フォルダ名/外部ファイル1.js"></script> <script type="text/javascript" src="./フォルダ名/外部ファイル2.js"></script> </head> <body><!-- 表示させたいところに --> <span id="rlinka0"></span> <span id="rlinka1"></span> <span id="rlinkb0"></span> <span id="rlinkb1"></span> </body> 一応これでうまく表示されました。 今のところ作ったJavaScriptのプログラムはページにコレしかないのですが、 正直このプログラムの内容も全て理解できていないので、少しずつ勉強していこうと思います。 回答してくださった皆様、本当にありがとうございました。

noname#20964
noname#20964
回答No.7

途中で口を挟むようで申し訳ありませんが、単純にこのようにしたらどうですか? -------------------------------- <HTML> <HEAD> <TITLE>ランダムリンク</TITLE> </HEAD> <BODY> <div id="link"> <a href="#">#</a><br />文章<br /> <a href="#">#</a><br />文章<br /> 文章 </div> <script type="text/javascript"> var a = document.getElementById('link').getElementsByTagName('a'); for(i=0;i<a.length;i++){ var random = Math.floor(Math.random() * 3); if(random == 0){ a[i].firstChild.nodeValue = 'サイト名1';a[i].setAttribute('href','URL1');} else if(random == 1) { a[i].firstChild.nodeValue = 'サイト名2';a[i].setAttribute('href','URL2');} else if(random == 2) { a[i].firstChild.nodeValue = 'サイト名3';a[i].setAttribute('href','URL3');} } </script> </BODY> </HTML> ------------------- ただ同じリンクが表示されることがありますが、同じ関数を複数回使っても同じですよね。 参考までに、appendChildは指定されたオブジェクト(この場合body)の最後に子供要素を追加するものですから、前の方の方法の場合createElement("div");でdivを作っているので</body>の直前にdivが追加されますよ。 そしてinnerHTMLでリンクをその中に書いているんです。 私の回答は最初にHTMLで仮のリンクを書いておいてそのリンクの文字とhrefの値を書き換えているだけです。 前の方の方法のdocument.body部分を変更すれば結果は同じに見えるのですが、自分でHTMLを書いた方が解り易いかなと思い書かせていただきました。 参考程度に見てください。

noname#46450
質問者

お礼

回答ありがとうございました。 <HTML>から書いてあったので、コピーしてすぐに試すことができました。 しかし、このままだとうまくいくのですが、外部ファイルや他の位置にスクリプトを移動させると うまく動作させることができませんでした。 最終的に使ったものを#9のところに載せておきます。 ありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.6

#5>指定した位置に表示されるのではなく、最後に追加される形になってしまいます。 仰るとおり、#3は、最後に追加するものです。 同じ位置というのがよくわからないのですが、 サイト名Xサイト名Yサイト名Zのように横並びになるということでしょうか? だったら、#2の方法で+=すればいいかと思います。 例 x.innerHTML += '<a href="URL1">サイト名1</a>';

noname#46450
質問者

お礼

すみません。説明の仕方が悪かったかもしれません。 表示させたいところに<script~></script>と書き込むと思うのですが、書き込んだところに表示されずにページの最後に表示されてしまいます。 例えばHTML内で、 ------------------------------------------------------ <body> <script~></script><br />文章<br /> <script~></script><br />文章<br /> 文章</body> ------------------------------------------------------ と記述したとすると、 ------------------------------------------------------ 文章 文章 文章 リンク(なぜかココは改行されて) リンク ------------------------------------------------------ と表示されてしまいます。 ページの最後に表示されてしまうということは、</body>の直前にスクリプトを書き込むことと同じということになってしまい、意味がなくなってしまうと思うのですが、この動作は正しいのでしょうか。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.5

#4補足>prototype.js prototype.js は、javascript のライブラリ(ツール集)です。 詳しくは、 http://www.imgsrc.co.jp/~kuriyama/prototype/prototype.js.html を参照されるといいでしょう。 よくできたライブラリは、ブラウザの違いを吸収するように作ってあります。そして、使用者は楽ができます。(欠点は余計な(必要以上の)機能が重くなることがあることですかね) #4お礼>とすると、最初のものしか動作しない id は、1つのHTML文書に1つだけしか指定できません。複数書いた場合の動作は未定義です。(ブラウザによってエラーになったり、配列になったり、最初のものだけが有効になったりする) そのような場合は、+= して追加していくようにするか、 #3のようにcreateElement するかすればいいと思います。

noname#46450
質問者

お礼

回答ありがとうございます。ライブラリをダウンロードして、紹介していただいたページを参考にしながら #3のものを使って書き直してみたところ、同じプログラムを複数回使用することはできるようになったのですが、 指定した位置に表示されるのではなく、最後に追加される形になってしまいます。 [外部ファイル] <!-- Event.observe(window, 'load', func, false); function func(){ var div = document.createElement("div"); var random = Math.floor(Math.random() * 3); if(random == 0) div.innerHTML = '<a href="URL1">サイト名1</a>'; else if(random == 1) div.innerHTML = '<a href="URL2">サイト名2</a>'; else if(random == 2) div.innerHTML = '<a href="URL3">サイト名3</a>'; document.body.appendChild(div); }; //--> [HTMLファイル] <head><script type="text/javascript" src="./prototype-1.4.0/dist/prototype.js"></script></head> <body><script type="text/javascript" src="./フォルダ名/ファイル名.js"></body> という感じです。 この方法ではムリなのでしょうか。。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#2>「window.onload を使って文書読み込み完了後に処理を開始する場合、 複数の外部ファイルで window.onload を記述すると、 次々上書きされて最後に代入された関数しか実行されない。」 #3>複数使おうとするとやはり最後のものしか実行されないようです。 window.onload に割り当てできるのは、1つの関数だからです。 addEventListener とか(IEではattachEvent )を使えば、1つのイベントに複数割り当てできると思います。

noname#46450
質問者

お礼

回答ありがとうございました。 attachEventを使って、複数実行させることができました。 しかし! 今はmognol_n様に教えていただいたようにプログラムを書いているのですが、 同じスクリプトを複数回使おうとすると、最初に記述したものしか動かないのです。。 (例)[HTML内]    <span id="rlink"></span>    <span id="rlink"></span>   とすると、最初のものしか動作しない これは仕様なのか、それとも書いたプログラムに原因があるのでしょうか。

noname#46450
質問者

補足

attachEventについて、 「CodeWeb [JavaScript]DOMっぽいイベントハンドラ、結局最後はprototype-js(後編)」 参照先:http://codeweb.seesaa.net/article/12114602.html というページを参考にさせていただいたのですが、 その下のほうで、prototype-jsをつかってクロスブラウザなプログラムを簡単に作れるようなことが書いてあります。 「prototype-js」という言葉が良くわからないのですが、クロスブラウザというところに興味があります。 もしかしたら的外れなことを言っているかもしれませんが、ヒントだけでもいただけると嬉しいです。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

window.onload = function (){ var div = document.createElement("div"); var random = Math.floor(Math.random() * 3); if(random == 0) div.innerHTML='<a href="URL1">サイト名1</a>'; else if(random == 1) div.innerHTML='<a href="URL2">サイト名2</a>'; else if(random == 2) div.innerHTML='<a href="URL3">サイト名3</a>'; document.body.appendChild(div); };

noname#46450
質問者

お礼

回答ありがとうございました。コピーして試してみました。 結果、無事に動作しました。 方法はいろいろあるようですね。 しかし複数使おうとするとやはり最後のものしか実行されないようです。。

  • mognol_n
  • ベストアンサー率61% (8/13)
回答No.2

document.writeですが、onloadイベント発生後に呼び出した場合はページ内容を上書きしてしまいます。 onloadを使う場合は以下のようにすれば良いでしょう。 [JavaScript] window.onload = function (){ var random = Math.floor(Math.random() * 3); var x = document.getElementById("rlink"); if (random == 0) x.innerHTML = '<a href="URL1">サイト名1</a>'; else if(random == 1) x.innerHTML = '<a href="URL2">サイト名2</a>'; else if(random == 2) x.innerHTML = '<a href="URL3">サイト名3</a>'; }; [HTML(リンクを表示したい部分に)] <span id="rlink"></span>または<div id="rlink"></div>

noname#46450
質問者

お礼

丁寧な回答ありがとうございました。 書かれている通りに(コピペみたいな感じですが)書き直して実行してみたところ、 無事動作しました。 が・・・複数実行させようとすると最後のものしか実行されませんでした。 少し調べてみたところ、 「window.onload を使って文書読み込み完了後に処理を開始する場合、 複数の外部ファイルで window.onload を記述すると、 次々上書きされて最後に代入された関数しか実行されない。」 参照先:http://www.remus.dti.ne.jp/~a-satomi/nikki/2003/07a.html#d09n02 というのを見つけました。 このページをコピーさせていただいたりして自分でも書いてみたのですが、うまくいきません。。

  • VCAT
  • ベストアンサー率20% (16/79)
回答No.1

関数名が被っているからでは?

noname#46450
質問者

お礼

回答ありがとうございました。 関数名、書かないでおきます。

関連するQ&A