家・車以外で、人生で一番奮発した買い物

お世話になります。
JavaScript初心者になります。

HTML上で、同じ処理をしたいものに、同じクラス名(notOnClick1st)をつけて、
Javascriptで動かそうとしても、動きません。

どこが悪いのでしょうか?

●ボックスに何の文字も入っていない時、あるボタン(下記のコードだと、4と8)を押せないようにしたい。
●setResult を HTML上で<body onLoad="setResult()">で読み込んでいるのですが、Uncaught ReferenceError: setResult is not defined (見つからない変数)というエラー出る。
●クラス名の取得だと、配列処理をしないといけないので、全部書くのが面倒なのでしたくない。(私の知識不足で、いい方法があるのかもしれませんが_ _;)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>test</title></head>
<body onLoad="setResult()">
<div id="wrap">
<table>
<tr>
<td colspan="4" class="white">
<input type="text" id="result">
</td>
</tr>
<tr>
<td>
<input type="button" value="1" onclick="edit(this)">
</td>
<td>
<input type="button" value="2" onclick="edit(this)">
</td>
<td>
<input type="button" value="3" onclick="edit(this)">
</td>
<td>
<input type="button" id="divide" class="notOnClick1st" value="4" onclick="edit(this)">
</td>
</tr>
<tr>
<td>
<input type="button" value="5" onclick="edit(this)">
</td>
<td>
<input type="button" value="6" onclick="edit(this)">
</td>
<td>
<input type="button" value="7" onclick="edit(this)">
</td>
<td>
<input type="button" id="divide" class="notOnClick1st" value="8" onclick="edit(this)">
</td>
</tr>
</table>
</div>
<script>
let result = document.getElementById("result");
function edit(elem) {
result.value = result.value + elem.value;
}
let notOnClick1stClass = document.querySelectorAll('.notOnClick1st');
notOnClick1stClass.forEach(function setResult(v) {
v = "";
if(v == "") {
notOnClick1stClass.disabled = true;
}else{
notOnClick1stClass.disabled = false;
}}
);
</script>
</body>
</html>

どなたかご教授いただければ幸いです。

質問者からの補足コメント

  • できました。
    いただいた回答を元に、自分なりに色々調べて、手を加えさせていただいて、ようやく、思っていたものが出来上がりました(文字オーバーで、コードがここに載せられないのが残念です)。

    みなさま、ありがとうございました。

    No.3の回答に寄せられた補足コメントです。 補足日時:2021/02/22 15:10

A 回答 (3件)

/** 現在の値の入力要素. */


var result = document.querySelector(対象);

/** ページをあるべき姿に更新. */
function updatePage(){
_ var x = (result.value == "");
_ document.querySelectorAll(対象).forEach(v=>v.disabled = x);
}
window.onload = updatePage; // 初期化

/** 現在の値を書き換え. */
function setResult(v){
_ result.value = String(v);
_ updatePage(); // 書き換えたから更新
}

/** 押しボタンで、現在の値に加算. */
function edit(elem) {
_ var r = parseFloat(result.value);
_ var a = parseFloat(elem.value);
_ setResult(r+a); // 書き換えは専門の処理で
}
この回答への補足あり
    • good
    • 0
この回答へのお礼

ご回答いただきありがとうございました。
お礼が遅くなり、申し訳ございません。
コードまで書いていただき、ありがとうございます!
(説明付きでとても嬉しいです)

jsをそのまま書き換えたのですが、

>_ var x =

アンダースコア(プライベート関数というもので間違いないですか)があると、「;」がないと言われてエラーになったので、削除してみたせいなのか、
他の数字を押すと、4の数字がどんどん足し算されていきました。
どこかしら、変更が必要ということですよね。
もう少し、元に試行錯誤してみます。

お礼日時:2021/02/18 17:56

<script>


document.addEventListener('click', (e)=>{
const result = document.getElementById("result");
if([...document.querySelectorAll('[type=button]')].includes(e.target)){
if(result.value!=="" || ![...document.querySelectorAll('.notOnClick1st')].includes(e.target)){
result.value+=e.target.value;
}
}
});
</script>

<div id="wrap">
<table>
<tr>
<td colspan="4" class="white">
<input type="text" id="result">
</td>
</tr>
<tr>
<td><input type="button" value="1" ></td>
<td><input type="button" value="2" ></td>
<td><input type="button" value="3" ></td>
<td><input type="button" class="notOnClick1st" value="4"></td>
</tr>
<tr>
<td><input type="button" value="5"></td>
<td><input type="button" value="6"></td>
<td><input type="button" value="7"></td>
<td><input type="button" class="notOnClick1st" value="8"></td>
</tr>
</table>
</div>
    • good
    • 0
この回答へのお礼

ご回答いただきありがとうございました。
お礼が遅くなり、申し訳ございません。
コードまで書いていただき、ありがとうございます!

できました!
…が、抜き出していないHTMLとJSに反映させると、その他が意図しない動作になりました _ _;。

私が実際に書いているのは計算機で、4は「=」に相当させていたので、1+3=(4)と押すと「4=」と必要のない「=」が最後に出てしまいます。


ちなみに、
if([...document.querySelectorAll('[type=button]')].includes(e.target)){

のdocument.query〜の前の [... はどういう意味ですか?
調べた方が悪いのか、何を示しているか分からなくて…。

お時間ございます時に、またご教授願えれば幸いです。

お礼日時:2021/02/18 17:04

こんにちは



>●setResult を HTML上で<body onLoad="setResult()">で読み込んで
>いるのですが、Uncaught ReferenceError: setResult is not defined
>(見つからない変数)というエラー出る。
メッセージの通りで、ご提示の関数定義方法だと関数名がスコープ内に無いため参照できないという意味です。
普通に、
 function setResult() { ~~ }
あるいは
 setResult = fnction() { ~~ }
のように定義しておけば、参照可能になるはずです。

>●クラス名の取得だと、配列処理をしないといけないので、全部書くのが
>面倒なのでしたくない。(私の知識不足で、いい方法があるのかもしれませんが
意味がよくわかりません。
通常は、個別に書くのが面倒なので、配列処理(あるいはリスト処理等)を行うものと認識していますが??

>●ボックスに何の文字も入っていない時、あるボタン(下記のコードだと、
>4と8)を押せないようにしたい。
onloadで処理しても良いですし、直接スクリプトタグ内で実行しても良いですが、例えば、

let notOnClick1stClass = document.querySelectorAll('.notOnClick1st');
notOnClick1stClass.forEach( e =>{ e.disabled = 'disabled'; });

などとしておくことで、初期設定としてdisabledを設定することが可能です。
(解除しない限り、入力できない状態のままになります。)
    • good
    • 0
この回答へのお礼

ご回答いただきありがとうございました。
お礼が遅くなり、申し訳ございません。

>function setResult() { ~~ }
私もそうかな、と思って(v)を取ったのですが、これだと、エラーになるんです。後ろのif文用に(v)を使っているから?


>●クラス名の取得だと、配列処理をしないといけないので〜

たぶん、私の知識が足りないのだと思います。
let notOnClick1st = document.getElementsByClassName("notOnClick1st")[0];
function setResult(v) {
v = "";
if(v == "") {
notOnClick1st.disabled = true;
}else{
notOnClick1st.disabled = false;
}}
で書くと、動くには動くのですが、[0]があるので、当然1つ目のものにしか効かないのです。[0]を取ると動きません…。


>onloadで処理しても良いですし、直接スクリプトタグ内で実行しても良いですが、例えば、let notOnClick1stClass = document.querySelectorAll('.notOnClick1st');
notOnClick1stClass.forEach( e =>{ e.disabled = 'disabled'; });

この解除がifなのかと思ったのですが、if文書き込んでみると、動かなくなるのです。
他に方法があるのですよね、きっと。

もう少し、試行錯誤してみます。

お礼日時:2021/02/18 16:23

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


おすすめ情報