プロが教える店舗&オフィスのセキュリティ対策術

ー作りたいものー
いくつかのセレクトボックスがあり、そこで選んだ内容によって選んだ内容の合計個数を求める。
例えば赤/青/黄のセレクトボックスが三つあり、二つは青を選んでひとつは黄色を選んだ場合に、青は2,黄は1というようにもとめたい(ほかのところで使える変数にする)。

ーつまづいている点ー
・変数にはスコープというものがあり、ある関数内で作った変数は他の関数では使えない。
→しかしどうすればよいのかわからない
・そもそも変数を定義することを、わざわざ関数の中に入れるべきなのか
→外に出してもよいのか
・ifを使っているが、ほかに何か方法はないのか
→valueではない方法などがあるのか
→さらに、ifの中もスコープらしいので、ifで変数で作っても外でつかう方法がわからない。

正しいコードを教えていただけると嬉しいです。
なお、javascriptをほとんど知らないので、わけのわからないことをしているかもしれませんので、ほかの部分の訂正等もいただけると嬉しいです。

(jqueryなどはさらにわからなくなっちゃうのでなしでおねがいします!
わがままですが、短さや早さとかは関係なく、なるべくわかりやすいコードだと嬉しいです)



ーコードー
[sumple.html]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="index.css" />
<script src="sumple.js"></script>
</head>
<body>
<select id="select1" onchange="fun1()">
<option value="1">赤</option>
<option value="2">青</option>
<option value="3">黄</option>
</select>
<select id="select2" onchange="fun2()">
<option value="1">赤</option>
<option value="2">青</option>
<option value="3">黄</option>
</select>
<select id="select3" onchange="fun3()">
<option value="1">赤</option>
<option value="2">青</option>
<option value="3">黄</option>
</select>
<button id="btn" onclick="btnclick()">ボタン</button>
</body>
</html>

[sumple.js]
function fun1() {
var selectval1 = document.getElementById("select1").value;
if (selectval1 == 1) {
var aka1 = 1;
}
if (selectval1 == 2) {
var ao1 = 1;
}
if (selectval1 == 3) {
var ki1 = 1;
}
}

function fun2() {
var selectval2 = document.getElementById("select2").value;
if (selectval2 == 1) {
var aka2 = 1;
}
if (selectval2 == 2) {
var ao2 = 1;
}
if (selectval2 == 3) {
var ki2 = 1;
}
}

function fun3() {
var selectval3 = document.getElementById("select3").value;
if (selectval3 == 1) {
var aka3 = 1;
}
if (selectval3 == 2) {
var ao3 = 1;
}
if (selectval3 == 3) {
var ki3 = 1;
}
}

function btnclick() {
var sumaka = aka1 + aka2 + aka3;
var sumao = ao1 + ao2 + ao3;
var sumki = ki1 + ki2 + ki3;
alert(sumaka,sumao,sumki)
}

よろしくお願いいたします。

A 回答 (3件)

こんにちは



すでに回答は出ていますけれど・・・

>・変数にはスコープというものがあり、ある関数内で
>作った変数は他の関数では使えない。
「使えない」と言うよりは、「参照できない」(=別の変数として扱われる)ということになります。
関数外からも参照したい場合は、関数外で定義しておけばよいです。
(両方のスコープ内になるように定義しておくという意味です)
あるいは、関数の「戻り値」として渡せば、「関数を呼び出せれば値を得る」ことができるようになります。
(関数そのものがスコープ外の場合は、呼び出すことができませんけれど…)

>→valueではない方法などがあるのか
DOM要素の値の参照なので、valueで取得するのが一般的と思います。
>正しいコードを教えていただけると嬉しいです。
方法や、記述法はいろいろありますので、「正しい」ものが一意にあるわけではありません。


さて、ご提示のスクリプトですが、No1様がご指摘のように「計算するのはボタンを押したとき」なので、ボタンを押したときの処理にまとめて記述すれば宜しいかと。
ご提示の場合、 関数fun1他はセレクト要素が変わった際に呼び出されますが、処理は行うものの結果的になにもしないので、俯瞰すれば「なにもしない」のと変わりないことになります。

また、javascriptの場合、変数を定義しただけ(あるいは未定義)で参照すると、「未定義」(=undefined)の値になります。
他の言語では、定義すれば「0」や空白(=「""」)に初期化するものもありますが、javascriptは違います。
例えば、変数Aを未定義のままで、
 alert( A + 1 );
とするとエラーになりますし、仮に定義しても、
 var A;
 alert( A + 1 );
では、1ではなくNaNと表示されます。(計算できないので)

この辺りを踏まえて、ベタにそのまま記述するなら、以下のひとつの関数で済むことになります。
ご提示のスクリプトをほぼそのまま利用するなら…
function btnclick() {
var aka1 = aka2 = aka3 = 0;
var ao1 = ao2 = ao3 = 0;
var ki1 = ki2 = ki3 = 0;

var selectval1 = document.getElementById("select1").value;
if (selectval1 == 1) aka1 = 1;
if (selectval1 == 2) ao1 = 1;
if (selectval1 == 3) ki1 = 1;

var selectval2 = document.getElementById("select2").value;
if (selectval2 == 1) aka2 = 1;
if (selectval2 == 2) ao2 = 1;
if (selectval2 == 3) ki2 = 1;

var selectval3 = document.getElementById("select3").value;
if (selectval3 == 1) aka3 = 1;
if (selectval3 == 2) ao3 = 1;
if (selectval3 == 3) ki3 = 1;

var sumaka = aka1 + aka2 + aka3;
var sumao = ao1 + ao2 + ao3;
var sumki = ki1 + ki2 + ki3;
alert(sumaka + "," + sumao + "," + sumki)
}


上記の記述は、同じような内容の処理が多いので変数を配列にして、同じ処理を関数化することで簡潔にすることも可能です。
const sVal = n => document.getElementById(n).value;
const btnclick = () =>{
let color = [0, 0, 0];
color[sVal('select1')-1]++;
color[sVal('select2')-1]++;
color[sVal('select3')-1]++;
alert(color.join(','));
}


更に、繰り返しを省いて簡略化することが可能ですが、現状の質問者様には少しずつ理解しにくい記述になっていくことになるかも知れません。
const btnclick = ()=>{
let color = [0, 0, 0];
document.querySelectorAll('select').forEach( e=>{ color[e.value - 1]++ });
alert(color.join(','));
}
    • good
    • 1

>・変数にはスコープというものがあり、ある関数内で作った変数は他の関数では使えない。


var ではなく let にしました。

>・そもそも変数を定義することを、わざわざ関数の中に入れるべきなのか
>→外に出してもよいのか
外に出しました。

>・ifを使っているが、ほかに何か方法はないのか
switchにしました。

>正しいコードを教えていただけると嬉しいです。
正しくはないかもしれませんが、以下で動くと思います。

[sumple.html]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="index.css" />
<script src="sumple.js"></script>
</head>
<body>
<select id="select1">
<option value="1">赤</option>
<option value="2">青</option>
<option value="3">黄</option>
</select>
<select id="select2">
<option value="1">赤</option>
<option value="2">青</option>
<option value="3">黄</option>
</select>
<select id="select3">
<option value="1">赤</option>
<option value="2">青</option>
<option value="3">黄</option>
</select>
<button id="btn" onclick="btnclick()">ボタン</button>
</body>
</html>

[sumple.js]
let sumaka;
let sumao;
let sumki;

function btnclick() {
sumaka = 0;
sumao = 0;
sumki = 0;
let selectval1 = document.getElementById("select1").value;
switch (selectval1) {
case '1':
sumaka += 1;
break;

case '2':
sumao += 1;
break;

case '3':
sumki += 1;
break;
}
let selectval2 = document.getElementById("select2").value;
switch (selectval2) {
case '1':
sumaka += 1;
break;

case '2':
sumao += 1;
break;

case '3':
sumki += 1;
break;
}
let selectval3 = document.getElementById("select3").value;
switch (selectval3) {
case '1':
sumaka += 1;
break;

case '2':
sumao += 1;
break;

case '3':
sumki += 1;
break;
}
alert('赤は ' + sumaka + '個\n青は ' + sumao + '個\n黄色は ' + sumki + '個\n');
}
    • good
    • 1
この回答へのお礼

このコードでやってみたところ、自分のやりたいことはできました!
先に外で変数を作って、関数の中で帰るという感じなのですね。
わからない部分もありますが、それは調べてみたいと思います。
回答ありがとうございます!

お礼日時:2021/05/03 07:05

まずHTMLがちゃんと書けていません。


FORM文が無い。

で。Javascriptの中からは document.フォーム名.変数名.value で変数の値を参照できます。

なので、三つのセレクトボックスそれぞれで選択された色ごとに変数値(value)を設けているのであれば、セレクトボックスごとの変数値を足し算するJavascript関数が1つあれば済むかと。。。
で、そのJavascript関数は画面上のボタンを押された時に動けばよいと。

でもって各変数に値がセットされないままボタンがクリックされることが無いよう、例えば各セレクトボックスの「赤」を初期値(selected指定)としておけばよい・・・とか。

参考まで。
    • good
    • 1
この回答へのお礼

回答ありがとうございます!

formをつけなくても思ったような動きになったのですが、(No.2さんのコードをやってみました)つけないとどのようなことがおこるのですか?
formの質問になって申し訳ありませんが、教えていただけると嬉しいです

お礼日時:2021/05/03 07:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!