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

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

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

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

解決済

繰り返し使う関数の書き方が分からない

syun1988
syun1988

総合スコア4

JavaScript

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

4回答

0グッド

0クリップ

360閲覧

投稿2022/12/04 02:03

前提

html

1<td class="score-p1"><input type="number"></td>

に値を入力したら

html

1<td id="sum-p1"></td>

へ計算結果を反映。

html

1<td class="score-p2"><input type="number"></td>

に値を入力したら

html

1<td id="sum-p2"></td>

へ計算結果を反映させたいです。

実現したいこと

現在、class="score-p1"に値を入力した際にid="sum-p1"に計算結果が反映されるJavaScriptは書けています。
今後、class="score-p2"、class="score-p3"………と列を増やしていく予定ですが、列を増やしたときのJavaScriptのスマートな書き方が分かりません。

該当のソースコード

html

1<table> 2 <tbody id="score"> 3 <tr> 4 <th>1</th> 5 <td class="score-p1"><input type="number"></td> 6 <td class="score-p2"><input type="number"></td> 7 </tr> 8 <tr> 9 <th>2</th> 10 <td class="score-p1"><input type="number"></td> 11 <td class="score-p2"><input type="number"></td> 12 </tr> 13 <tr> 14 <th>3</th> 15 <td class="score-p1"><input type="number"></td> 16 <td class="score-p2"><input type="number"></td> 17 </tr> 18 <tr> 19 <th>4</th> 20 <td class="score-p1"><input type="number"></td> 21 <td class="score-p2"><input type="number"></td> 22 </tr> 23 <tr> 24 <th>5</th> 25 <td class="score-p1"><input type="number"></td> 26 <td class="score-p2"><input type="number"></td> 27 </tr> 28 </tbody> 29 <tfoot> 30 <tr> 31 <th>合計</th> 32 <td id="sum-p1"></td> 33 <td id="sum-p2"></td> 34 </tr> 35 </tfoot> 36</table>

以下はclass="score-p1"に数値を入力したときid="sum-p1"に結果が反映されるJavaScriptです。

js

1window.addEventListener('DOMContentLoaded', () => { 2 3score.addEventListener('input', () => { 4 // 要素を取得 5 const score = document.getElementById('score'); 6 const scoreElements = score.querySelectorAll('.score-p1 input'); 7 var price = 0; 8 9 // 取得した要素を反復処理 10 for (let i = 0; i < scoreElements.length; i += 1) { 11 const element = scoreElements[i]; 12 if (!isNaN(element.valueAsNumber)) 13 price += element.valueAsNumber; 14 } 15 16 document.getElementById('sum-p1').innerText = price; 17}); 18 19})

class="score-p2"、class="score-p3"………と列を増やしたときにどういう書き方をすべきかご教示いただけたらと思います。
どうぞよろしくお願いいたします。

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

回答4

2

あえてp1、p2の入力をわけて考える必要はないですね
常に入力があるごとに計算してください

javascript

1document.addEventListener('input', ()=>{ 2 ['p1','p2'].forEach(x=>{ 3 const v=[...document.querySelectorAll(`.score-${x} [type=number]`)].reduce((x,y)=>x+Number(y.value),0); 4 document.querySelector(`#sum-${x}`).textContent=v; 5 }); 6});

投稿2022/12/05 02:47

yambejp

総合スコア108937

spoofy_dragon, syun1988😄を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

<td class="score-p1"><td id="sum-p1"> ではなくて、<td class="score" data-group="p1"> <td class="sum" data-group="p1"> のように役割とグループを分けると多少すっきりするかと思います。

js

1score.addEventListener('input', e => { 2 const group = e.target.closest('.score').dataset.group; 3 const score = document.getElementById('score'); 4 const scoreElements = score.querySelectorAll(`.score[data-group="${group}"] input`); 5 document.querySelector(`.sum[data-group="${group}"]`).textContent = 6 [...scoreElements].map(input => isNaN(input.valueAsNumber) ? 0 : input.valueAsNumber).reduce((a, c) => a + c); 7});

投稿2022/12/05 00:21

int32_t

総合スコア17087

syun1988😄を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

1

ベストアンサーまで出ちゃったのですが、目を見張るようなスマートなコードを見ることなく終わってしまったので、全然スマートじゃない汚いのを置いときます。class属性は基本的にCSSから参照されるので、見た目に関係ないところで使わない方がいい気がします。

JavaScript

1window.addEventListener('DOMContentLoaded', () => { 2 const score = document.getElementById('score'); 3 const suminfos = Array.from(document.querySelectorAll('td[id^="sum-"]')) 4 .reduce((m, e)=>{ 5 const id = e.id.substring(4); 6 m[id] = { 7 "elem": e, 8 "scores": Array.from(score.querySelectorAll(`td.score-${id} input`)) 9 }; 10 return m; 11 }, {}); 12 const handler = (ev) => { 13 const classList = Array.from(ev.currentTarget.parentElement.classList); 14 const id = classList.filter(e => e.match(/^score-/))[0].substring(6); 15 const suminfo = suminfos[id]; 16 suminfo.elem.textContent = suminfo.scores.reduce((s, v)=>{ 17 return s + (v.valueAsNumber ? v.valueAsNumber : 0); 18 }, 0); 19 }; 20 Object.entries(suminfos).forEach(([id, info]) => { 21 info.scores.forEach(e => { 22 e.addEventListener('input', handler); 23 }) 24 }); 25}); 26

他の回答も出てきてくれたのでコンセプトだけ書いておきます。

このコードのコンセプトは速度です(まだ速く出来ると思いますが)。イベント発生時DOMにqueryをかけることなく、適応的に計算結果を反映しています。

投稿2022/12/04 13:35

編集2022/12/05 03:32
dameo

総合スコア594

syun1988😄を押しています

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

0

ベストアンサー

すっごく力技っぽくなっていますけど,こんな感じでどうですか?

js

1window.addEventListener('DOMContentLoaded', () => { 2 score.addEventListener('input', () => { 3 // 要素を取得 4 const score = document.getElementById('score'); 5 6 for (let a = 1; a <= 2; a ++) { // classname をここで切り替えていく 7 let scoreElements = score.querySelectorAll('.score-p' + String(a) + ' input'); 8 var price = 0; 9 10 // 取得した要素を反復処理 11 for (let i = 0; i < scoreElements.length; i += 1) { 12 const element = scoreElements[i]; 13 if (!isNaN(element.valueAsNumber)) 14 price += element.valueAsNumber; 15 } 16 17 document.getElementById('sum-p' + String(a)).innerText = price; 18 } 19 }); 20});

ただ,今後列を増やしていく上で現状のソースコードがスマートかと言われるとう〜んってなられているのではないでしょうか?

よろしければ,以下のソースコードも試してみてください.(こっちもスマートか言われる微妙ですが…)

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <script src="./main.js"></script> 7</head> 8<body> 9 <main role="main"> 10 <div id="__"></div> 11 </main> 12</body> 13</html>

js

1// main.js 2 3/** 4 * Tableを作る 5 * @param {Number} rowNum 行数 6 * @param {Number} score-p の数 7 */ 8class Score { 9 constructor(rowNum, pNum) { 10 this.rowNum = rowNum; 11 this.pNum = pNum; 12 this.TABLE = document.createElement('table'); 13 14 this.setTbody(); 15 this.setTfoot(); 16 } 17 18 setTbody() { 19 let tbody = document.createElement('tbody'); 20 this.priceArray = new Array(); 21 22 for (let i = 0; i < this.rowNum; i ++) { 23 let tr = document.createElement('tr'); 24 let th = document.createElement('th'); 25 th.innerText = String(i + 1); 26 tr.appendChild(th); 27 28 this.priceArray[i] = new Array(); 29 30 for (let j = 0; j < this.pNum; j ++) { 31 let td = document.createElement('td'); 32 td.className = "score-p" + String(j + 1); 33 34 let input = document.createElement('input'); 35 input.type = "number"; 36 37 td.appendChild(input); 38 tr.appendChild(td); 39 40 this.priceArray[i][j] = 0; 41 42 // 値が入力されたら加算処理 43 input.addEventListener('input', (e) => { 44 this.priceArray[i][j] = Number(e.target.value); 45 this.add(j); 46 }) 47 } 48 tbody.appendChild(tr); 49 50 } 51 52 this.TABLE.appendChild(tbody); 53 } 54 55 setTfoot() { 56 let tfoot = document.createElement('tfoot'); 57 let tr = document.createElement('tr'); 58 let th = document.createElement("th"); 59 th.innerText = "合計"; 60 tr.appendChild(th); 61 62 for (let j = 0; j < this.pNum; j ++) { 63 let td = document.createElement('td'); 64 td.id = "sum-p" + String(j + 1); 65 tr.appendChild(td); 66 } 67 68 tfoot.appendChild(tr); 69 this.TABLE.appendChild(tfoot); 70 } 71 72 add(pNum) { 73 let price = 0; 74 for (let i = 0; i < this.rowNum; i ++) { 75 price += this.priceArray[i][pNum]; 76 } 77 78 document.getElementById("sum-p" + String(pNum + 1)).innerText = price; 79 } 80} 81 82 83window.onload = () => { 84 const SCORE = new Score(5, 3); 85 document.getElementById('__').appendChild(SCORE.TABLE); 86 87 console.log(SCORE); 88}

投稿2022/12/04 08:15

m0605

総合スコア14

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

syun1988

2022/12/04 13:21

ご回答ありがとうございました! 前者のコードで思い通りの挙動になりました。 お陰様で悩んでいた箇所が解決できました。 後者のコードはもっと自分がレベルアップしてから試してみたいと思います。 ありがとうございました。

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

JavaScript

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