🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

4回答

1940閲覧

javascript 同じ処理をまとめる

hj_zebra

総合スコア10

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/10/29 04:09

https://teratail.com/questions/69420
上記URLを参照しましたが私の理解力が乏しいためわかりませんでした。

やりたいこととしましては、
カウントアップ、カウントダウンの部分をまとめて記述したいです。
function count_up_btn1(one,two,three){
}
変数を増やそうとしているためこの記述方法以外を教えていただけると幸いです。

よろしくお願いします。

html

1<html> 2<head> 3 <title>TAG index Webサイト</title> 4<script type="text/javascript"> 5var one = 0; 6var two = 0; 7var three = 0; 8var total = 0; 9 10function count_up_btn1(){ 11 //カウンタに 1 を加算 12 document.getElementById( "one" ).innerHTML = ++one; 13 document.getElementById( "total" ).innerHTML = ++total; 14} 15function count_down_btn1(){ 16 //カウンタから 1 を減算 17 document.getElementById( "one" ).innerHTML = --one; 18 document.getElementById( "total" ).innerHTML = --total; 19} 20 21function count_up_btn2(){ 22 //カウンタに 1 を加算 23 document.getElementById( "two" ).innerHTML = ++two; 24 document.getElementById( "total" ).innerHTML = ++total; 25} 26 27function count_down_btn2(){ 28 //カウンタから 1 を減算 29 document.getElementById( "two" ).innerHTML = --two; 30 document.getElementById( "total" ).innerHTML = --total; 31} 32 33function count_up_btn3(){ 34 //カウンタに 1 を加算 35 document.getElementById( "three" ).innerHTML = ++three; 36 document.getElementById( "total" ).innerHTML = ++total; 37} 38 39function count_down_btn3(){ 40 //カウンタから 1 を減算 41 document.getElementById( "three" ).innerHTML = --three; 42 document.getElementById( "total" ).innerHTML = --total; 43} 44 45</script> 46 47</head> 48<body> 49<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 50 <tr> 51 <th>種類</th> 52 <th>プラス</th> 53 <th>マイナス</th> 54 <th>合計<br>回数</th> 55 <th>残り<br>回数</th> 56 </tr> 57 <tr> 58 <td align="center">1</td> 59 <td align=center><input type="button" value="+" onClick="count_up_btn1()"></input></td> 60 <td align=center><input type="button" value="-" onClick="count_down_btn1()"></input></td> 61 <td align=center><span id="one">0</span></td> 62 <td></td> 63 </tr> 64 <td align="center">2</td> 65 <td align=center><input type="button" value="+" onClick="count_up_btn2()"></input></td> 66 <td align=center><input type="button" value="-" onClick="count_down_btn2()"></input></td> 67 <td align=center><span id="two">0</span></td> 68 <td></td> 69 </tr> 70 <td align="center">3</td> 71 <td align=center><input type="button" value="+" onClick="count_up_btn3()"></input></td> 72 <td align=center><input type="button" value="-" onClick="count_down_btn3()"></input></td> 73 <td align=center><span id="three">0</span></td> 74 <td></td> 75 </tr> 76</table> 77<br> 78<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 79<tr> 80 <th>合計<br>回数</th> 81</tr> 82<tr> 83 <td align=center><span id="total">0</span></td> 84</tr> 85</table> 86</body> 87</html> 88

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

こんにちは

リファクタリングの指針として、以下の2点が考えられます。

  • one, two, three, ... という id や変数を使わないようにすること
  • イベント属性を使わずに、控えめなJavaScript(※追記2) にすること

以下、上記を踏まえた修正案の一例です。

html

1<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 2 <tr> 3 <th>種類</th> 4 <th>プラス</th> 5 <th>マイナス</th> 6 <th>合計<br>回数</th> 7 <th>残り<br>回数</th> 8 </tr> 9 <tr> 10 <td align="center">1</td> 11 <td align="center"><input type="button" value="+" /></td> 12 <td align="center"><input type="button" value="-" /></td> 13 <td align="center"><span>0</span></td> 14 <td></td> 15 </tr> 16 <tr> 17 <td align="center">2</td> 18 <td align="center"><input type="button" value="+" /></td> 19 <td align="center"><input type="button" value="-" /></td> 20 <td align="center"><span>0</span></td> 21 <td></td> 22 </tr> 23 <tr> 24 <td align="center">3</td> 25 <td align="center"><input type="button" value="+" /></td> 26 <td align="center"><input type="button" value="-" /></td> 27 <td align="center"><span>0</span></td> 28 <td></td> 29 </tr> 30</table> 31<br> 32<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 33<tr> 34 <th>合計<br>回数</th> 35</tr> 36<tr> 37 <td align=center><span id="total">0</span></td> 38</tr> 39</table>

javascript

1document.addEventListener('DOMContentLoaded', function() { 2 3 const totalSpan = document.getElementById('total'); 4 const rows = [...document.querySelectorAll('table:first-of-type tr')]; 5 6 rows.forEach((row, rowIndex) => { 7 if (rowIndex === 0) return; 8 9 const counterSpan = row.querySelector('span'); 10 const buttons = [...row.querySelectorAll('input')]; 11 12 buttons.forEach((btn, btnIndex) => { 13 btn.addEventListener('click', () => { 14 [counterSpan, totalSpan].forEach(span => { 15 span.textContent = +span.textContent + (btnIndex ? -1 : 1); 16 }); 17 }); 18 }); 19 }); 20 21});

上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、増えた行に対応するためのコード追加、修正をする必要がないものになっています。たとえば、上記のHTMLのテーブルの行を単に4行追加して計7行にしたとしても、javascriptのコードには何も手を加える必要がないです。

ご質問に挙げられている元のjavascriptのコードを、テーブルが何行になっても追加、修正する必要がないものにするためには、

  • one, two, three, ... という id や変数を使わないようにすること

が、リファクタリングしていく際の指針のひとつになります。

追記1: onclick属性にスクリプトを書く例

hj_zebraさんのご質問にある元のコードで、HTMLの下記の部分

html

1<input type="button" value="+" onClick="count_up_btn1()">

のように、input要素のonclick属性にスクリプトを直接書くという手法をそのまま使いつつ、かつ、コードをまとめる例を挙げておきます。

修正方法としては、上記を

html

1<input type="button" value="+" onclick="count(this)">

のようにして、クリックされたボタンを引数にとる関数count(button) を作っておいて、どのボタンがクリックされてもこれに処理させるようにします。以下、その一例です。(初めに挙げた回答と同じく、one, two, three を使わないようにもしています。)

html

1<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 2 <tr> 3 <th>種類</th> 4 <th>プラス</th> 5 <th>マイナス</th> 6 <th>合計<br>回数</th> 7 <th>残り<br>回数</th> 8 </tr> 9 <tr> 10 <td align="center">1</td> 11 <td align="center"><input type="button" value="+" onclick="count(this)" /></td> 12 <td align="center"><input type="button" value="-" onclick="count(this)" /></td> 13 <td align="center"><span>0</span></td> 14 <td></td> 15 </tr> 16 <tr> 17 <td align="center">2</td> 18 <td align="center"><input type="button" value="+" onclick="count(this)" /></td> 19 <td align="center"><input type="button" value="-" onclick="count(this)" /></td> 20 <td align="center"><span>0</span></td> 21 <td></td> 22 </tr> 23 <tr> 24 <td align="center">3</td> 25 <td align="center"><input type="button" value="+" onclick="count(this)" /></td> 26 <td align="center"><input type="button" value="-" onclick="count(this)" /></td> 27 <td align="center"><span>0</span></td> 28 <td></td> 29 </tr> 30</table> 31<br> 32<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 33<tr> 34 <th>合計<br>回数</th> 35</tr> 36<tr> 37 <td align=center><span id="total">0</span></td> 38</tr> 39</table>

以下は、 上記のボタンクリック時に使用する関数count(button) の一例です。

javascript

1function count(button) { 2 const diff = +`${button.value}1`; 3 const spans = [ 4 document.getElementById('total'), 5 button.closest('tr').querySelector('span') 6 ]; 7 spans.forEach(span => { 8 span.textContent = +span.textContent + diff; 9 }); 10}

追記2: 控えめなJavaScript

ご質問にある、下記のHTML

html

1<input type="button" value="+" onClick="count_up_btn1()">

のように、HTML要素のonclickなどの属性に直接スクリプトを書くことで、イベントを処理させる書き方に対して、この回答の冒頭に書いたコードの下記の部分

javascript

1btn.addEventListener('click', () => { 2 ・・・ 3});

のように、プログラムの中でイベントハンドラを設定する書き方は、控えめなJavaScript(Unobtrusive JavaScript)と呼ばれることがあります。

HTML要素の属性である onclickonchange はイベント属性と呼ばれますが、MDNのイベント属性の説明には、以下のように、使用を非推奨とする旨が書かれています。

警告: これらの属性を使うことは避けるべきです。これは HTML を巨大化し可読性を下げます。情報と振る舞いの関心事が正しく分離されておらず、発見が困難なバグを生み出します。その上に、Event 属性の使い方はほとんどの場合、Window オブジェクト上のグローバル関数にスクリプトを晒す原因になります。これはグローバルの名前空間を汚染します。

これらの属性が魅力的で簡単に使うことができたとしても、これを使うのは避けるべきです。代わりに、イベントリスナーを追加する為には EventTarget.addEventListener() 関数を使ってください。

投稿2019/10/29 05:35

編集2019/10/30 01:19
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

処理をまとめるならこんな感じ
※微調整しました

javascript

1 2<script> 3window.addEventListener('DOMContentLoaded', ()=>{ 4 [].forEach.call(document.querySelectorAll('.count'),x=>{ 5 x.addEventListener('click',()=>{ 6 var view=x.closest('tr').querySelector('.view'); 7 var total=document.querySelector('#total'); 8 view.textContent=parseInt(view.textContent)+x.classList.contains('up')-x.classList.contains('down') 9 total.textContent=[].map.call(document.querySelectorAll('.view'),x=>parseInt(x.textContent)).reduce((x,y)=>x+y); 10 }); 11 }); 12}); 13</script> 14 15</head> 16<body> 17<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 18 <tr> 19 <th>種類</th> 20 <th>プラス</th> 21 <th>マイナス</th> 22 <th>合計<br>回数</th> 23 <th>残り<br>回数</th> 24 </tr> 25 <tr> 26 <td align="center">1</td> 27 <td align=center><input type="button" value="+" class="count up"></input></td> 28 <td align=center><input type="button" value="-" class="count down"></input></td> 29 <td align=center><span class="view">0</span></td> 30 <td></td> 31 </tr> 32 <td align="center">2</td> 33 <td align=center><input type="button" value="+" class="count up"></input></td> 34 <td align=center><input type="button" value="-" class="count down"></input></td> 35 <td align=center><span class="view">0</span></td> 36 <td></td> 37 </tr> 38 <td align="center">3</td> 39 <td align=center><input type="button" value="+" class="count up"></input></td> 40 <td align=center><input type="button" value="-" class="count down"></input></td> 41 <td align=center><span class="view">0</span></td> 42 <td></td> 43 </tr> 44</table> 45<br> 46<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 47<tr> 48 <th>合計<br>回数</th> 49</tr> 50<tr> 51 <td align=center><span id="total">0</span></td> 52</tr> 53</table> 54

投稿2019/10/29 05:03

編集2019/10/29 05:27
yambejp

総合スコア116694

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

修正案の一例です。なるべく元の感じを殺さないように修正してみました。

HTML

1<html> 2<head> 3 <title>TAG index Webサイト</title> 4<script type="text/javascript"> 5var counter = { 6 one: 0, 7 two: 0, 8 three: 0, 9 total: 0 10}; 11 12function count_up(id){ 13 //カウンタに 1 を加算 14 document.getElementById(id).innerHTML = ++counter[id]; 15 document.getElementById("total").innerHTML = ++counter['total']; 16} 17 18function count_down(id){ 19 //カウンタから 1 を減算 20 document.getElementById(id).innerHTML = --counter[id]; 21 document.getElementById("total").innerHTML = --counter['total']; 22} 23 24</script> 25 26</head> 27<body> 28<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 29 <tr> 30 <th>種類</th> 31 <th>プラス</th> 32 <th>マイナス</th> 33 <th>合計<br>回数</th> 34 <th>残り<br>回数</th> 35 </tr> 36 <tr> 37 <td align="center">1</td> 38 <td align=center><input type="button" value="+" onClick="count_up('one')"></input></td> 39 <td align=center><input type="button" value="-" onClick="count_down('one')"></input></td> 40 <td align=center><span id="one">0</span>回</td> 41 <td></td> 42 </tr> 43 <td align="center">2</td> 44 <td align=center><input type="button" value="+" onClick="count_up('two')"></input></td> 45 <td align=center><input type="button" value="-" onClick="count_down('two')"></input></td> 46 <td align=center><span id="two">0</span>回</td> 47 <td></td> 48 </tr> 49 <td align="center">3</td> 50 <td align=center><input type="button" value="+" onClick="count_up('three')"></input></td> 51 <td align=center><input type="button" value="-" onClick="count_down('three')"></input></td> 52 <td align=center><span id="three">0</span>回</td> 53 <td></td> 54 </tr> 55</table> 56<br> 57<table border="1"cellspacing="0" cellpadding="5" bordercolor="black"> 58<tr> 59 <th>合計<br>回数</th> 60</tr> 61<tr> 62 <td align=center><span id="total">0</span>回</td> 63</tr> 64</table> 65</body> 66</html>

投稿2019/10/29 06:51

編集2019/10/29 06:52
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

どこまで理解できているのでしょうか。
失礼ですが、質問にあるサンプル、自分なりにやったものでしょうか。
たまに切り貼りしただけの、全く理解すらしていない(そもそもJavaScriptって何?おいしいの?っていうレベルだったり)場合があります。

知識レベルに応じた説明があるので、できるだけ「どこまで理解できたのか」「どこが不明瞭なのか」を記述しすると説明しやすいです。


[追記1]

サンプルソースは自分で作成したものになります。

Okです。関数の組み方は...ご存じですよね?
わからないのなら、入門書(または入門サイト)をお読みください。
まずは基礎ができていないと無理ですから。

ボタンの数が多く、できるだけ汎用性を持たせた関数を作成したいということですよね。

まず、基本的な部分を考えてみましょう。

JavaScript

1function count_up_btn1(){ 2 //カウンタに 1 を加算 3 document.getElementById( "one" ).innerHTML = ++one; 4 document.getElementById( "total" ).innerHTML = ++total; 5} 6function count_down_btn1(){ 7 //カウンタから 1 を減算 8 document.getElementById( "one" ).innerHTML = --one; 9 document.getElementById( "total" ).innerHTML = --total; 10} 11 12function count_up_btn2(){ 13 //カウンタに 1 を加算 14 document.getElementById( "two" ).innerHTML = ++two; 15 document.getElementById( "total" ).innerHTML = ++total; 16} 17 18function count_down_btn2(){ 19 //カウンタから 1 を減算 20 document.getElementById( "two" ).innerHTML = --two; 21 document.getElementById( "total" ).innerHTML = --total; 22} 23 24function count_up_btn3(){ 25 //カウンタに 1 を加算 26 document.getElementById( "three" ).innerHTML = ++three; 27 document.getElementById( "total" ).innerHTML = ++total; 28} 29 30function count_down_btn3(){ 31 //カウンタから 1 を減算 32 document.getElementById( "three" ).innerHTML = --three; 33 document.getElementById( "total" ).innerHTML = --total; 34}

がやりたいこと(最終的に行いたいこと)ですよね。

共通部分を見ると、

常に id が"one", "two", "tree" のどれかをインクリメント( ++oneとか )やデクリメント ( --one とか ) して、id がtotal のエリアを インクリメントまたはデクリメントしていますね。

つまり、共通項だけをまとめて書くと

// ただし<..> とあるのは何かしらの変数または定数だとして document.getElementById( <ID> ).innerHTML = <増減>; document.getElementById( "total" ).innerHTML = <増減>;

ですよね。

それなら、単純にこの式をコード化すればいいかと思います。

ただし、<ID> と<増減>だけが不定。
それなら、これを管理する関数 を作って、これに管理させる。

ただ、私の書き方ですと、プロトタイプっていう、ほかの言語だとクラス...を変化させたようなものを使う必要があるので、関数で結構です。
ヒント: プロトタイプ JavaScript

JavaScript

1// プロトタイプ NumberManagerを定義 2 3function calcNumberWithId(id){ 4 // 仮に "one"のときは減算で "two"なら加算すると仮定 5 if( id == "one" ){ 6 // ここで one をインクリメントする 7 // あと total も 8 return one; 9 }else if( id == "two" ){ 10 // ここでtwo をデクリメントする 11 // あと total も 12 return two; 13 } 14 // 処理されなかった... 15 return undefined; 16}

みたいにしておけば、

グローバルエリアとかでNumberManagerのインスタンスを生成しておいて、

JavaScript

1// ただし<..> とあるのは何かしらの変数または定数だとして 2// また numberManager は NumberManagerのオブジェクトだとして 3function pushButton( id ){ 4 // 関数calcNumberWithIdを介して操作し、戻り値のnumを設定する 5 var num = calcNumberWithId(id); 6 document.getElementById( id ).innerHTML = num; 7 document.getElementById( "total" ).innerHTML = total; 8}

みたいに簡略化できる。

もっといい方法があるのかもしれませんが、私ならこういう風にするかなぁ。

追記:
あ、忘れていた...
呼び出し側である、<input type="button" value="-" onClick="count_down_btn3()"></input> では、

count_down_btn3関数じゃなくて、pushButton関数を呼び出してください。

例:

JavaScript

1<input type="button" value="-" onClick="pushButton('three')"></input>

すると、

関数Aが関数Bを呼び出している...みたいな体で書くと、

pushButton( "three" );
みたいになる。

後から考えると、countDown_pushButton( "three" ); countUp_pushButton( "three" ); とかに分離してもいいかなぁ。
(大雑把な考え方は一緒)

投稿2019/10/29 04:18

編集2019/10/29 05:39
BeatStar

総合スコア4962

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hj_zebra

2019/10/29 04:43

>BeatStarさん サンプルソースは自分で作成したものになります。 javasscriptはほんの少ししか理解できていないため説明などしていただけると助かります。
BeatStar

2019/10/29 04:45

追記しますね。
hj_zebra

2019/10/29 04:58

お願いします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問