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

解決済みの質問

同じメソッドを複数回、呼び出しは可能でしょうか

<script>
var arg = new Object, p = location.search.substring(1).split('&');
for(var i=0; p[i]; i++){
var kv = p[i].split('=');
arg[kv[0]] = kv[1];
}
window.onload = function (){
if(01 == arg.id){document.getElementById("type").innerHTML = "あなたはA型";}
else if(02 == arg.id){document.getElementById("type").innerHTML = "あなたはB型";}
else if(03 == arg.id){document.getElementById("type").innerHTML = "あなたはO型";}
else if(04 == arg.id){document.getElementById("type").innerHTML = "あなたはAB型";}
else {document.getElementById("type").innerHTML = "わかりません";}
}
</script>

サイトへの表示は
<span id="type"></span>
と記述することで、問題なく表示ることができています。

しかし、これを複数個所に記述すると
最初の箇所しか表示しません。

同じページの複数の箇所(希望は4か所)に表示させるためには、
どのようにすればよいのでしょうか。

投稿日時 - 2019-02-09 14:37:10

QNo.9586087

困ってます

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

>しかし、これを複数個所に記述すると
「これ」の主語がわかりませんが。
HTMLだとしたら、idはもともとユニーク(2つ同じものがないもの)を
前提なので、複数回書くこと自体NGです。

なので、type1,type2,type3,と違うIDを割り付けるようにすればOKです。
if(01 == arg.id){document.getElementById("type").innerHTML = "あなたはA型";}
"type"という部分は、ここでつかっているわけですから、ここを変数にして、
var id="type1";
if(01 == arg.id){document.getElementById(id).innerHTML = "あなたはA型";}
と、名前を変数からにすれば、何セットでも、量産できますよ。

それと、比較に"04"と書いてますが、数字は4であり、
"04"ではないので、4で比較したほうがいいですよ。
010は、数字の10ではなく、8になるので、バカなバグのもとになります。
(先頭に0を書くと、10進数ではなく、8進数つまり、7->8で桁上がりします)
(010-1=07 という事)

という事で、最終回答
function waaa(id){
switch(arg.id) { /* この変数も本来はパラメタに入れるべきだが */
case 1:document.getElementById(id).innerHTML = "あなたはA型";break;
case 2:document.getElementById(id).innerHTML = "あなたはB型";break;
case 3:document.getElementById(id).innerHTML = "あなたはO型";break;
case 4:document.getElementById(id).innerHTML = "あなたはAB型";break;
default:document.getElementById(id).innerHTML = "わかりません";break;
}
}
window.onload = function (){
var i;
for (i=1;i<=4;i++) { /* 仮で、type1~type4まであることを仮定 */
waaa("type"+i);
}
}
でどうでしょうか?
if を switchに変えているのは、すべてが同一の変数の為です。
if でネストし続ける場合は、他の変数で比較をしたい場合に問題が起こりにくく、
同じ変数がいくつか?の場合は、switchにしたほうが、問題が起こりにくいでしょう。

投稿日時 - 2019-02-09 20:13:36

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

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

回答(4)

ANo.4

とりあえず id="" を class="" に変更して以下みたいにすれば通ると思うけど…

<span class="my-blood-type"></span>

window.onload = function (){
var my_str = "Your blood-type is... ", my_arg = arg.id, my_arr = document.getElementsByClassName('my-blood-type'), cnt = my_arr.length;

if ( '01' == my_arg ) {
my_str = my_str +'A';
}
else if ( '02' == my_arg ) {
my_str = my_str +'B';
}
else if ( '03' == my_arg ) {
my_str = my_str +'O';
}
else if ( '04' == my_arg ) {
my_str = my_str +'AB';
}
else {
my_str = my_str +'Unknown.';
}

for (var i=0; i<cnt; i++) {
my_arr[i].innerHTML = my_str;
}
}

例文の最初の方は恐らくアクセス時の引数で処理を振り分けてるんだと思うけど、まあ弄らずにそのままでメインのHTML表示部分のみ変更してみました。後、URLに引数として渡した場合、その値はそのままだと通常は文字列型なので 01==id みたいな数値演算比較すると期待した挙動にならないです。

P.S.
Javascript関数の getElementById() てそのまま英語で書いてある通りで、「IDによって、エレメントを、ゲットする」て意味なので。つまり "Elements(複数)" では無くあくまでも "Element(単数)" しかゲットしない。

従って同一ページ内に同じ名前の要素(同一ID名の要素)が複数存在した場合、ページ内で上から順に探して行って最初にヒットした時点で動作終了する様になってます。

これは何も間違って無くて正しい動作。W3C準拠のHTML5でも同一ページ内にID要素は1つしか存在しない事を推奨してるので。HTML構文的に間違いとは言えないけど、同じID名の要素が複数存在する事を基本的に想定しない。

同一ページ内に同じ名前の要素を複数個存在させたい場合、CLASS名を割り振る事が推奨されてるし、JavascriptもそういうHTML構文を想定して作られている。なので関数名も getElementsByClassName() という風に複数形になってる。

投稿日時 - 2019-02-09 23:57:50

var a=["わかりません","あなたはA型","あなたはB型","あなたはO型","あなたはAB型"];
document.getElementById(id).innerHTML = (arg.id>=1 && arg.id<=4)? a[arg.id]:a[0];
先ほどswitchで書いた部分ですが、と、まとめてもOKです。
たったの2行にまとまりますけどね。

(なんとかかんとか)? なんとかを満たすならここが展開:満たさないならここが展開;
なので、1~4なら、a配列の1~4番目に書き変わり、
満たしていない場合はa[0]つまり"わかりません"が代入されるという感じ。
さらにコードを短くしたいなら、「あなたは?型」の?以外は変化していないので、
"あなたは"+a[arg.id]+"型" と1回だけ書いて配列から文字を取れば全体では
さらに減りますが、たいした効果はないでしょうけど。

投稿日時 - 2019-02-09 20:30:25

ANo.1

>しかし、これを複数個所に記述すると

「これ」とはどの部分?
<script>~</script>のことなら、window.onload に代入するので1つしか動きません。
<span id="type"></span>のことなら、idはページで1つだけです。

投稿日時 - 2019-02-09 20:00:42