ヘッダの中にscriptを書いたほうが良いと言われたので移植してみたのですが、
なぜか動かなくなりました。
とても慎重に行ったのでコピペ漏れがあるとかは無いと思います。
out.printを用いて上から見ていったところ、★の箇所で止まっている様でした。
これはコピペ移植する前の状態の時に、
サンプルソースから引っ張ってきた時からくっついていたもので、
正直存在意義が分からなかったので消そうとしたらエラーが発生するので
見てみぬフリをしてやり過ごそうとした所でした。
質問の要点は2つです。
なぜscriptの位置を動かしただけでエラーが発生したのか。
このエラーが出ている★箇所は本来どういう目的で作用していて、
どう対応すれば本来の動きに戻るか、です。
どうかよろしくお願いします。
↓動いていた時のコード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>情報入力画面</title>
<meta http-equiv="Content-Script-Type" content="text/javascript">
</head>
<body bgcolor = "#bce2e8">
<form name="registration" method="post" action="" onSubmit="return check()">
<hr width="100%" size="4">
<font size="7" color="#0000ff"><div align=center>情報入力画面</div></font>
<hr width="100%" size="4">
<table width="400px" height="60%" border="0" align="center" valign ="middle">
<tbody>
<tr>
<td valign ="middle">
<div>生年月日<select name="selectYear" id="selectYear" onchange="setSelectMonth()">
</select>年<select name="selectMonth" id="selectMonth" onchange="setSelectDate()">
</select>月<select name="selectDate" id="selectDate">
</select>日</div>
<div align="center"><input type="submit" value="登録"</input></div>
</td>
</tr>
</tbody>
</table>
<hr width="100%" size="4">
</form>
<script type="text/javascript">//属性
<!--
/*=========[ 生年月日 : プルダウン選択 ]=========*/
var Now = new Date();
var NowYear = Now.getFullYear();
/*[ オプションを更新(年) ]*/
function setSelectYear(){
for(var y=NowYear-40; y<NowYear-17; y++){
//selectボックスIDからElementの取得
var selectElement = document.getElementById("selectYear");
//<option>要素を追加
var option = document.createElement("option");
//optionのvalue属性を設定
option.value = y;
//リストに表示するテキストの設定
option.text = y;
//セレクトボックスにオプションを追加
selectElement.appendChild(option);
}
setSelectMonth();
}
setSelectYear();//★★★存在意義がわからなかった★★★
/*[ オプションを更新(月) ]*/
function setSelectMonth(){
var selectElement = document.getElementById("selectMonth");
var child;
//セレクトボックスの子要素を取得しつつループ
while(child = selectElement.firstChild){
//セレクトボックスから子要素を削除
selectElement.removeChild(child);
}
for(var m=1; m<=12; m++){
var option = document.createElement("option");
option.value = m;
option.text = m;
selectElement.appendChild(option);
}
setSelectDate();
}
/*[ オプションを更新(日) ]*/
function setSelectDate(){
//選択された年を取得
var Year =
document.registration.selectYear.options[
document.registration.selectYear.selectedIndex].value;
//選択された月を取得
var Month =
document.registration.selectMonth.options[
document.registration.selectMonth.selectedIndex].value;
//うるう年に対応出来る月の最終日を取得
var lastDate = new Date(Year,Month,0).getDate();
var selectElement = document.getElementById("selectDate");
var child;
while(child = selectElement.firstChild){
selectElement.removeChild(child);
}
for(var d=1; d<=lastDate; d++){
var option = document.createElement("option");
option.value = d;
option.text = d;
selectElement.appendChild(option);
}
}
// -->
</script>
</body>
</html>
↓移植して動かなくなったコード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>情報入力画面</title>
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">//属性
<!--
/*=========[ 生年月日 : プルダウン選択 ]=========*/
var Now = new Date();
var NowYear = Now.getFullYear();
/*[ オプションを更新(年) ]*/
setSelectYear();
function setSelectYear(){
for(var y = NowYear-40; y <= NowYear-17; y++){
//selectボックスIDからElementの取得
var selectElement = document.getElementById("selectYear");
//<option>要素を追加
var option = document.createElement("option");
//optionのvalue属性を設定
option.value = y;
//リストに表示するテキストの設定
option.text = y;
//セレクトボックスにオプションを追加
selectElement.appendChild(option);
}
setSelectMonth();
}
setSelectYear();//★★★ここで止まる★★★
/*[ オプションを更新(月) ]*/
function setSelectMonth(){
var selectElement = document.getElementById("selectMonth");
var child;
//セレクトボックスの子要素を取得しつつループ
while(child = selectElement.firstChild){
//セレクトボックスから子要素を削除
selectElement.removeChild(child);
}
for(var m = 1; m <= 12; m++){
var option = document.createElement("option");
option.value = m;
option.text = m;
selectElement.appendChild(option);
}
setSelectDate();
}
/*[ オプションを更新(日) ]*/
function setSelectDate(){
//選択された年を取得
var Year =
document.registration.selectYear.options[
document.registration.selectYear.selectedIndex].value;
//選択された月を取得
var Month =
document.registration.selectMonth.options[
document.registration.selectMonth.selectedIndex].value;
//うるう年に対応出来る月の最終日を取得
var lastDate = new Date(Year,Month,0).getDate();
var selectElement = document.getElementById("selectDate");
var child;
while(child = selectElement.firstChild){
selectElement.removeChild(child);
}
for(var d = 1; d <= lastDate; d++){
var option = document.createElement("option");
option.value = d;
option.text = d;
selectElement.appendChild(option);
}
}
// -->
</script>
</head>
<body bgcolor = "#bce2e8">
<form name="registration" method="post" action="" onSubmit="return check()">
<hr width="100%" size="4">
<font size="7" color="#0000ff"><div align=center>情報入力画面</div></font>
<hr width="100%" size="4">
<table width="400px" height="60%" border="0" align="center" valign ="middle">
<tbody>
<tr>
<td valign ="middle">
<div>生年月日<select name="selectYear" id="selectYear" onchange="setSelectMonth()">
</select>年<select name="selectMonth" id="selectMonth" onchange="setSelectDate()">
</select>月<select name="selectDate" id="selectDate">
</select>日</div>
<div align="center"><input type="submit" value="登録"</input></div>
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
修正を行いました。
ここで止まるっていう箇所の内容がselectMonthになっていましたが、
selectYearの移し間違いです。
質問している問題点とは別の単なる質問するときに間違えたミスです。
回答者様が困らない様以後気をつけます(汗)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+3
setSelectYear()でset系の関数を全て呼んでいるので呼ぶ必要があるのはこれだけです。
winsow.onloadでDOMが読み込み終わってからsetSelectYear()を呼ぶといいんじゃないですかね。
以下全文
var Now = new Date();
var NowYear = Now.getFullYear();
window.onload = function(){
setSelectYear();
}
function check(){
//変数に入力された文字列から文字列の前後にある空白文字を抜いて格納。
var nametxt = document.registration.name.value.replace(/(^\s+)|(\s+$)/g, "");
var fromtxt = document.registration.from.value.replace(/(^\s+)|(\s+$)/g, "");
var telltxt = document.registration.tel.value.replace(/(^\s+)|(\s+$)/g, "");
//名前欄が未入力・空白の時にアラートを表示し、フォーカスする。
if(nametxt == ""){
window.alert("名前が未入力です");
document.registration.name.focus();
return false;
//住所欄が未入力・空白の時にアラートを表示し、フォーカスする。
}else if(fromtxt == ""){
window.alert("住所が未入力です");
document.registration.from.focus();
return false;
//電話番号欄が未入力・空白の時にアラートを表示し、フォーカスする。
}else if(telltxt == ""){
window.alert("電話番号が未入力です");
document.registration.tel.focus();
return false;
//電話番号欄の文字列が数字ではない時にアラートを表示し、フォーカスする。
}else if(telltxt.match(/[^0-9]+/)){
window.alert("電話番号に数字以外の文字が入力されています")
document.registration.tel.focus();
return false;
//未入力・空白項目がなく、電話番号に数字以外の文字列も入力されていない場合はtrueを送り処理を完了させる。
}else{
return true;
}
}
/*[ オプションを更新(年) ]*/
function setSelectYear(){
for(var y = NowYear-40; y <= NowYear-17; y++){
//selectボックスIDからElementの取得
var selectElement = document.getElementById("selectYear");
//<option>要素を追加
var option = document.createElement("option");
//optionのvalue属性を設定
option.value = y;
//リストに表示するテキストの設定
option.text = y;
//セレクトボックスにオプションを追加
selectElement.appendChild(option);
}
setSelectMonth();
}
/*[ オプションを更新(月) ]*/
function setSelectMonth(){
var selectElement = document.getElementById("selectMonth");
var child;
//セレクトボックスの子要素を取得しつつループ
while(child = selectElement.firstChild){
//セレクトボックスから子要素を削除
selectElement.removeChild(child);
}
for(var m = 1; m <= 12; m++){
var option = document.createElement("option");
option.value = m;
option.text = m;
selectElement.appendChild(option);
}
setSelectDate();
}
/*[ オプションを更新(日) ]*/
function setSelectDate(){
//選択された年を取得
var Year =
document.registration.selectYear.options[
document.registration.selectYear.selectedIndex].value;
//選択された月を取得
var Month =
document.registration.selectMonth.options[
document.registration.selectMonth.selectedIndex].value;
//うるう年に対応出来る月の最終日を取得
var lastDate = new Date(Year,Month,0).getDate();
var selectElement = document.getElementById("selectDate");
var child;
while(child = selectElement.firstChild){
selectElement.removeChild(child);
}
for(var d = 1; d <= lastDate; d++){
var option = document.createElement("option");
option.value = d;
option.text = d;
selectElement.appendChild(option);
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
まだ、DOM(画面の要素など)が準備ができていない段階でjavascriptが実行され、document.getElementByIdによる要素の取得が失敗しています。
エラーを回避するには、DOMの準備が完了してからスクリプトが実行されるようにすべきです。「window.onload」で検索するといいでしょう。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
ID=selectYearが読み込めないかと思います。
ですので、HTMLを読み込んでから実行するように
window.onload = function(){
setSelectYear();
setSelectMonth();
};
にしては如何でしょう?
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
<head>
の段階で実行されてしまうと、下にあるドロップダウンなどのフォームが読み込まれていない状態なので、エラーになります。素直に元の位置においておくか、onload
など適当なタイミングで実行されるようにしましょう。
なお、
setSelectYear();//★★★この存在意義がわからなかった★★★
ですが、この上で作った関数を呼び出しています。関数は定義しただけだと、何も起きません。投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
動かない理由はみなさんが言っている通り、実行タイミングが変わったからです。
イメージ的には荷物を取りに行ったけど荷物が無くてエラーみたいな感じですかね。
つまり取りに行く先が用意できるまで待つ必要があります。
その場合いくつか方法があり、その一つがbodyの閉じタグ前での定義です。
window.onloadを使用する方法やaddEventListenerやattachEventでloadイベントをセットする方法がありますが前者は最良の方法とは言えないと思われます。
後者はブラウザ間実装の違いがあります(jQueryなどのライブラリはその差異を吸収し動作します)。
body閉じタグ前での宣言はデメリットらしいデメリットがないので選択肢の一つとして割と優秀でありだと思います。
また少し前からbody閉じタグ前でスクリプトを使用するのが一番いいのではないかという意見が出始めているように思います。
(理由としましては最後にJSを実行することで表示を早くすることにつながる。loadイベントのブラウザ間差異を気にしなくてよくなることなど)
何か参考になれば
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
なぜscriptの位置を動かしただけでエラーが発生したのか。見たところ、「位置を動かしただけ」ではないようですね。
まずはそのままコピペしてみてはいかがでしょう?
このエラーが出ている★箇所は本来どういう目的で作用していて、
どう対応すれば本来の動きに戻るか。
setSelectMonth();//★★★ここで止まる★★★
を消せばうごくのではないでしょうか?
function hogehoge(){・・・}
はこういう動きをしますよ~という定義をしているだけなので、
これだけではJSは実行されません。
hogehoge();
と書くことで関数を実行します。
スクリプトの流れとしては
setSelectYear()の中でsetSelectMonth()が実行され、
setSelectMonth()の中でsetSelectDate()が実行されています。
なので、
setSelectYear();
と書けば、setSelectMonth()もsetSelectDate()も実行されるということです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 90.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2015/05/27 18:04
呼ぶのはYearだけで全部連動するのですね、やっと説明出来ない箇所がなくなりました。
ありがとう御座います♪