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

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

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

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

Q&A

解決済

6回答

2654閲覧

javascriptとbodyの順を逆にしたら動かなくなった。

R.lawliet

総合スコア41

JavaScript

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

0グッド

0クリップ

投稿2015/05/27 08:18

編集2015/05/27 09:00

作成したプルダウンメニューについての評価を頂いた際に、
ヘッダの中にscriptを書いたほうが良いと言われたので移植してみたのですが、
なぜか動かなくなりました。

とても慎重に行ったのでコピペ漏れがあるとかは無いと思います。
out.printを用いて上から見ていったところ、★の箇所で止まっている様でした。

これはコピペ移植する前の状態の時に、
サンプルソースから引っ張ってきた時からくっついていたもので、
正直存在意義が分からなかったので消そうとしたらエラーが発生するので
見てみぬフリをしてやり過ごそうとした所でした。

質問の要点は2つです。
なぜscriptの位置を動かしただけでエラーが発生したのか。

このエラーが出ている★箇所は本来どういう目的で作用していて、
どう対応すれば本来の動きに戻るか、です。

どうかよろしくお願いします。

↓動いていた時のコード

lang

1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<html> 3 <head> 4 <title>情報入力画面</title> 5 <meta http-equiv="Content-Script-Type" content="text/javascript"> 6 </head> 7 <body bgcolor = "#bce2e8"> 8 9 <form name="registration" method="post" action="" onSubmit="return check()"> 10 <hr width="100%" size="4"> 11 <font size="7" color="#0000ff"><div align=center>情報入力画面</div></font> 12 <hr width="100%" size="4"> 13 <table width="400px" height="60%" border="0" align="center" valign ="middle"> 14 15 <tbody> 16 <tr> 17 <td valign ="middle"> 18 <div>生年月日<select name="selectYear" id="selectYear" onchange="setSelectMonth()"> 19 </select>年<select name="selectMonth" id="selectMonth" onchange="setSelectDate()"> 20 </select>月<select name="selectDate" id="selectDate"> 21 </select>日</div> 22 <div align="center"><input type="submit" value="登録"</input></div> 23 </td> 24 </tr> 25 </tbody> 26 </table> 27 <hr width="100%" size="4"> 28 </form> 29<script type="text/javascript">//属性 30<!-- 31 32/*=========[ 生年月日 : プルダウン選択 ]=========*/ 33 34var Now = new Date(); 35var NowYear = Now.getFullYear(); 36 37/*[ オプションを更新(年) ]*/ 38 39function setSelectYear(){ 40 for(var y=NowYear-40; y<NowYear-17; y++){ 41 42 //selectボックスIDからElementの取得 43 var selectElement = document.getElementById("selectYear"); 44 45 //<option>要素を追加 46 var option = document.createElement("option"); 47 //optionのvalue属性を設定 48 option.value = y; 49 //リストに表示するテキストの設定 50 option.text = y; 51 //セレクトボックスにオプションを追加 52 selectElement.appendChild(option); 53 } 54 setSelectMonth(); 55 56} 57setSelectYear();//★★★存在意義がわからなかった★★★ 58 59/*[ オプションを更新(月) ]*/ 60function setSelectMonth(){ 61var selectElement = document.getElementById("selectMonth"); 62var child; 63//セレクトボックスの子要素を取得しつつループ 64while(child = selectElement.firstChild){ 65 //セレクトボックスから子要素を削除 66 selectElement.removeChild(child); 67} 68 69for(var m=1; m<=12; m++){ 70 var option = document.createElement("option"); 71 option.value = m; 72 option.text = m; 73 74 selectElement.appendChild(option); 75 76 } 77 setSelectDate(); 78} 79 80/*[ オプションを更新(日) ]*/ 81 82function setSelectDate(){ 83 //選択された年を取得 84 var Year = 85 document.registration.selectYear.options[ 86 document.registration.selectYear.selectedIndex].value; 87 //選択された月を取得 88 var Month = 89 document.registration.selectMonth.options[ 90 document.registration.selectMonth.selectedIndex].value; 91 92 //うるう年に対応出来る月の最終日を取得 93 var lastDate = new Date(Year,Month,0).getDate(); 94 95 var selectElement = document.getElementById("selectDate"); 96 var child; 97 while(child = selectElement.firstChild){ 98 selectElement.removeChild(child); 99 } 100 101 for(var d=1; d<=lastDate; d++){ 102 var option = document.createElement("option"); 103 option.value = d; 104 option.text = d; 105 selectElement.appendChild(option); 106 } 107} 108// --> 109</script> 110</body> 111 112</html>

↓移植して動かなくなったコード

lang

1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2<html> 3 <head> 4 <title>情報入力画面</title> 5 <meta http-equiv="Content-Script-Type" content="text/javascript"> 6 <script type="text/javascript">//属性 7<!-- 8/*=========[ 生年月日 : プルダウン選択 ]=========*/ 9 10var Now = new Date(); 11var NowYear = Now.getFullYear(); 12 13/*[ オプションを更新(年) ]*/ 14setSelectYear(); 15function setSelectYear(){ 16 for(var y = NowYear-40; y <= NowYear-17; y++){ 17 18 //selectボックスIDからElementの取得 19 var selectElement = document.getElementById("selectYear"); 20 21 //<option>要素を追加 22 var option = document.createElement("option"); 23 //optionのvalue属性を設定 24 option.value = y; 25 //リストに表示するテキストの設定 26 option.text = y; 27 //セレクトボックスにオプションを追加 28 selectElement.appendChild(option); 29 } 30 setSelectMonth(); 31 32} 33setSelectYear();//★★★ここで止まる★★★ 34 35/*[ オプションを更新(月) ]*/ 36function setSelectMonth(){ 37 var selectElement = document.getElementById("selectMonth"); 38 var child; 39 40//セレクトボックスの子要素を取得しつつループ 41while(child = selectElement.firstChild){ 42 //セレクトボックスから子要素を削除 43 selectElement.removeChild(child); 44} 45 46for(var m = 1; m <= 12; m++){ 47 var option = document.createElement("option"); 48 option.value = m; 49 option.text = m; 50 51 selectElement.appendChild(option); 52 53 } 54 setSelectDate(); 55} 56 57/*[ オプションを更新(日) ]*/ 58 59function setSelectDate(){ 60 //選択された年を取得 61 var Year = 62 document.registration.selectYear.options[ 63 document.registration.selectYear.selectedIndex].value; 64 //選択された月を取得 65 var Month = 66 document.registration.selectMonth.options[ 67 document.registration.selectMonth.selectedIndex].value; 68 69 //うるう年に対応出来る月の最終日を取得 70 var lastDate = new Date(Year,Month,0).getDate(); 71 72 var selectElement = document.getElementById("selectDate"); 73 var child; 74 while(child = selectElement.firstChild){ 75 selectElement.removeChild(child); 76 } 77 for(var d = 1; d <= lastDate; d++){ 78 var option = document.createElement("option"); 79 option.value = d; 80 option.text = d; 81 selectElement.appendChild(option); 82 } 83} 84// --> 85 </script> 86 </head> 87 <body bgcolor = "#bce2e8"> 88 89 <form name="registration" method="post" action="" onSubmit="return check()"> 90 <hr width="100%" size="4"> 91 <font size="7" color="#0000ff"><div align=center>情報入力画面</div></font> 92 <hr width="100%" size="4"> 93 <table width="400px" height="60%" border="0" align="center" valign ="middle"> 94 95 <tbody> 96 <tr> 97 <td valign ="middle"> 98 99 100 <div>生年月日<select name="selectYear" id="selectYear" onchange="setSelectMonth()"> 101 </select>年<select name="selectMonth" id="selectMonth" onchange="setSelectDate()"> 102 </select>月<select name="selectDate" id="selectDate"> 103 </select>日</div> 104 <div align="center"><input type="submit" value="登録"</input></div> 105 </td> 106 </tr> 107 </tbody> 108 </table> 109 </form> 110</body> 111 112</html>

修正を行いました。
ここで止まるっていう箇所の内容がselectMonthになっていましたが、
selectYearの移し間違いです。

質問している問題点とは別の単なる質問するときに間違えたミスです。
回答者様が困らない様以後気をつけます(汗)

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

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

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

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

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

guest

回答6

0

ベストアンサー

DOM要素が読み込めていないために起きているエラーです。
setSelectYear()でset系の関数を全て呼んでいるので呼ぶ必要があるのはこれだけです。
winsow.onloadでDOMが読み込み終わってからsetSelectYear()を呼ぶといいんじゃないですかね。
以下全文

lang

1var Now = new Date(); 2var NowYear = Now.getFullYear(); 3 4window.onload = function(){ 5 setSelectYear(); 6} 7 8function check(){ 9 //変数に入力された文字列から文字列の前後にある空白文字を抜いて格納。 10 var nametxt = document.registration.name.value.replace(/(^\s+)|(\s+$)/g, ""); 11 var fromtxt = document.registration.from.value.replace(/(^\s+)|(\s+$)/g, ""); 12 var telltxt = document.registration.tel.value.replace(/(^\s+)|(\s+$)/g, ""); 13 14 //名前欄が未入力・空白の時にアラートを表示し、フォーカスする。 15 if(nametxt == ""){ 16 window.alert("名前が未入力です"); 17 document.registration.name.focus(); 18 return false; 19 20 //住所欄が未入力・空白の時にアラートを表示し、フォーカスする。 21 }else if(fromtxt == ""){ 22 window.alert("住所が未入力です"); 23 document.registration.from.focus(); 24 return false; 25 26 //電話番号欄が未入力・空白の時にアラートを表示し、フォーカスする。 27 }else if(telltxt == ""){ 28 window.alert("電話番号が未入力です"); 29 document.registration.tel.focus(); 30 return false; 31 32 //電話番号欄の文字列が数字ではない時にアラートを表示し、フォーカスする。 33 }else if(telltxt.match(/[^0-9]+/)){ 34 window.alert("電話番号に数字以外の文字が入力されています") 35 document.registration.tel.focus(); 36 return false; 37 38 //未入力・空白項目がなく、電話番号に数字以外の文字列も入力されていない場合はtrueを送り処理を完了させる。 39 }else{ 40 return true; 41 } 42} 43 44/*[ オプションを更新(年) ]*/ 45function setSelectYear(){ 46 for(var y = NowYear-40; y <= NowYear-17; y++){ 47 48 //selectボックスIDからElementの取得 49 var selectElement = document.getElementById("selectYear"); 50 51 //<option>要素を追加 52 var option = document.createElement("option"); 53 //optionのvalue属性を設定 54 option.value = y; 55 //リストに表示するテキストの設定 56 option.text = y; 57 //セレクトボックスにオプションを追加 58 selectElement.appendChild(option); 59 } 60 setSelectMonth(); 61 62} 63 64/*[ オプションを更新(月) ]*/ 65function setSelectMonth(){ 66 var selectElement = document.getElementById("selectMonth"); 67 var child; 68 69 //セレクトボックスの子要素を取得しつつループ 70 while(child = selectElement.firstChild){ 71 //セレクトボックスから子要素を削除 72 selectElement.removeChild(child); 73 } 74 75 for(var m = 1; m <= 12; m++){ 76 var option = document.createElement("option"); 77 option.value = m; 78 option.text = m; 79 80 selectElement.appendChild(option); 81 82 } 83 setSelectDate(); 84} 85 86/*[ オプションを更新(日) ]*/ 87function setSelectDate(){ 88 //選択された年を取得 89 var Year = 90 document.registration.selectYear.options[ 91 document.registration.selectYear.selectedIndex].value; 92 //選択された月を取得 93 var Month = 94 document.registration.selectMonth.options[ 95 document.registration.selectMonth.selectedIndex].value; 96 97 //うるう年に対応出来る月の最終日を取得 98 var lastDate = new Date(Year,Month,0).getDate(); 99 100 var selectElement = document.getElementById("selectDate"); 101 var child; 102 while(child = selectElement.firstChild){ 103 selectElement.removeChild(child); 104 } 105 for(var d = 1; d <= lastDate; d++){ 106 var option = document.createElement("option"); 107 option.value = d; 108 option.text = d; 109 selectElement.appendChild(option); 110 } 111}

投稿2015/05/27 08:34

Yasha_Wedyue

総合スコア830

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

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

R.lawliet

2015/05/27 09:04

なるほど、Yearを呼ぶ位置が変なとこにあったんですね。。。 呼ぶのはYearだけで全部連動するのですね、やっと説明出来ない箇所がなくなりました。 ありがとう御座います♪
guest

0

特に何もせずにスクリプトを書いた場合、それはその場で実行されます。つまり、まだ<head>の段階で実行されてしまうと、下にあるドロップダウンなどのフォームが読み込まれていない状態なので、エラーになります。素直に元の位置においておくか、onloadなど適当なタイミングで実行されるようにしましょう。

なお、

setSelectYear();//★★★この存在意義がわからなかった★★★

ですが、この上で作った関数を呼び出しています。関数は定義しただけだと、何も起きません

投稿2015/05/27 08:34

maisumakun

総合スコア145183

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

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

R.lawliet

2015/05/27 09:06

関数は自然に実行されはしないのですね。 モヤモヤがなくなりました。ありがとうございます。
guest

0

HTMLが読み込まれる前にjavascriptが走ってしまって、
ID=selectYearが読み込めないかと思います。

ですので、HTMLを読み込んでから実行するように

lang

1window.onload = function(){ 2 setSelectYear(); 3 setSelectMonth(); 4};

にしては如何でしょう?

投稿2015/05/27 08:32

IshibashiTanaka

総合スコア152

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

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

R.lawliet

2015/05/29 00:24

具体的な手段をありがとうございます♪ 他の方の回答と照らし合わせながら参照すると、 どうやらYearの中でMonthの呼び出しはできてるので、 onloadするのはYearだけで良さそうですね。
guest

0

動かなくなった原因はスクリプトが実行されるタイミングが早まったためです。
まだ、DOM(画面の要素など)が準備ができていない段階でjavascriptが実行され、document.getElementByIdによる要素の取得が失敗しています。

エラーを回避するには、DOMの準備が完了してからスクリプトが実行されるようにすべきです。「window.onload」で検索するといいでしょう。

投稿2015/05/27 08:31

orange0190

総合スコア1698

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

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

0

そもそもhead内に記載するのが良いのかは場合によるかと。
動かない理由はみなさんが言っている通り、実行タイミングが変わったからです。
イメージ的には荷物を取りに行ったけど荷物が無くてエラーみたいな感じですかね。
つまり取りに行く先が用意できるまで待つ必要があります。
その場合いくつか方法があり、その一つがbodyの閉じタグ前での定義です。

window.onloadを使用する方法やaddEventListenerやattachEventでloadイベントをセットする方法がありますが前者は最良の方法とは言えないと思われます。
後者はブラウザ間実装の違いがあります(jQueryなどのライブラリはその差異を吸収し動作します)。
body閉じタグ前での宣言はデメリットらしいデメリットがないので選択肢の一つとして割と優秀でありだと思います。
また少し前からbody閉じタグ前でスクリプトを使用するのが一番いいのではないかという意見が出始めているように思います。
(理由としましては最後にJSを実行することで表示を早くすることにつながる。loadイベントのブラウザ間差異を気にしなくてよくなることなど)

何か参考になれば

投稿2015/05/27 12:04

Cf_cwd

総合スコア730

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

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

R.lawliet

2015/05/29 00:32

別サイドからの視点をありがとう御座います。 選択肢が広がる様なアドバイスはとても参考になります。 scriptが先なサンプルとbodyを閉じる寸前に書く例とあったので非常に混乱していたのですが、そういう背景があったのですね。 新米初心者の目線で見ると、 今回みたいなエラーも未然に回避出来るのに、 なぜscriptを先に書く風潮があったのかが不思議でなりません。
Cf_cwd

2015/05/29 00:48

私は初級者から中級者の間辺り(だといいの)です。 それ以前はHTMLファイルにJSのコードを直書きするのが主流だったようです。 先頭で読み込むのはこれも場合によりますよね、CSSファイルなら先頭の方がいいでしょう。なぜなら読み込みが完了するまでCSSで定義されたデザインが反映されないということにつながりますし。つまりJSでもページが読み込みされる(正確にはDOMが構築される前に)実行されてほしいものはHTMLの先頭辺りにおいておくといい訳ですね。 速度について反例があったのでURLを載せておきます。 http://memocarilog.info/jquery/5842
R.lawliet

2015/05/29 02:02

CSSはまだ触れておりません。 扱う時の参考にします。 もしかしたらチームで扱う時に上だったり下だったり人によって違うと嫌だから、 CSSに合わせて上にしろって感じの流れかもしれませんね。 参考URL読みました。 なるほど、速度に関しては色々説は上がってるんですね。 まぁコードの数はちょっとでも減らしたいですし、 scriptの場合は、基本的に下、先に読み込ませたい例外の時は上、、、って感じが僕的にはしっくりです。
guest

0

なぜscriptの位置を動かしただけでエラーが発生したのか。

見たところ、「位置を動かしただけ」ではないようですね。
まずはそのままコピペしてみてはいかがでしょう?

このエラーが出ている★箇所は本来どういう目的で作用していて、
どう対応すれば本来の動きに戻るか。

setSelectMonth();//★★★ここで止まる★★★
を消せばうごくのではないでしょうか?

function hogehoge(){・・・}
はこういう動きをしますよ~という定義をしているだけなので、
これだけではJSは実行されません。

hogehoge();
と書くことで関数を実行します。

スクリプトの流れとしては
setSelectYear()の中でsetSelectMonth()が実行され、
setSelectMonth()の中でsetSelectDate()が実行されています。

なので、
setSelectYear();
と書けば、setSelectMonth()もsetSelectDate()も実行されるということです。

投稿2015/05/27 08:41

Yoh

総合スコア94

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

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

R.lawliet

2015/05/27 09:02

質問で★を付け足す時に一回そこを削除してしまい、 書き直す時にMonthになっちゃっていたみたいです。 Yearの間違いです。 上の方でsetSelectYearを呼び出せば良かったのですね! 何とかなりました。ありがとう御座います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問