teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

17

テキスト修正

2019/10/30 01:19

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -1,7 +1,12 @@
1
1
  こんにちは
2
2
 
3
- 以下、修正案一例です。
3
+ リファクタリングの指針として、以下の2点が考えられます。
4
4
 
5
+ - `one`, `two`, `three`, ... という id や変数を使わないようにすること
6
+ - イベント属性を使わずに、控えめなJavaScript(※追記2) にすること
7
+
8
+ 以下、上記を踏まえた修正案の一例です。
9
+
5
10
  ```html
6
11
  <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">
7
12
  <tr>

16

テキスト修正

2019/10/30 01:19

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -71,21 +71,18 @@
71
71
  - **動作確認用 CodePen: ** [https://codepen.io/jun68ykt/pen/mddMGbV?editors=1010](https://codepen.io/jun68ykt/pen/mddMGbV?editors=1010)
72
72
 
73
73
 
74
- 参考になれば幸いです。
75
74
 
76
- ### 追記1
75
+ 上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、増えた行に対応するためのコード加、修正をする必要がないものになっています。たとえば、上のHTMLのテーブルの行を単に4行追加して計7行にしたとしても、javascriptのコードには何も手を加える必要がないです。
77
76
 
78
- 上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、何らかの追加、修正する必要がないものになっています。以下は、上記のHTMLのテーブルの行を単に7行にしただけで、javascriptのコードには何も手を加えていないです。
77
+ - **テーブルの行を7行にす:** [https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010](https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010)
79
78
 
80
- - **テーブルを7行:** [https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010](https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010)
79
+ ご質問に挙げられている元のjavascriptのコードを、テーブルが何行になっても追加、修正する必要がないものにするめには、
81
80
 
82
- ご質問に挙げられている元のjavascriptのコードを、テーブルの行が何行になっても追加、修正する必要がないものにするには、
83
-
84
81
  - `one`, `two`, `three`, ... という id や変数を使わないようにすること
85
82
 
86
83
  が、リファクタリングしていく際の指針のひとつになります。
87
84
 
88
- ### 追記2
85
+ ### 追記1: onclick属性にスクリプトを書く例
89
86
 
90
87
  hj_zebraさんのご質問にある元のコードで、HTMLの下記の部分
91
88
  ```html
@@ -97,7 +94,7 @@
97
94
  ```html
98
95
  <input type="button" value="+" onclick="count(this)">
99
96
  ```
100
- のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるようにします。以下、その一例です。(先の追記1書い意図と同じく、`one`, `two`, `three` を使わないようにもしています。)
97
+ のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるようにします。以下、その一例です。(初め挙げ回答と同じく、`one`, `two`, `three` を使わないようにもしています。)
101
98
 
102
99
  ```html
103
100
  <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">
@@ -158,7 +155,7 @@
158
155
  ```
159
156
  - **動作確認用CodePen: ** [https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010](https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010)
160
157
 
161
- ### 追記3
158
+ ### 追記2: 控えめなJavaScript
162
159
 
163
160
  ご質問にある、下記のHTML
164
161
  ```html

15

テキスト修正

2019/10/30 00:45

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -174,7 +174,7 @@
174
174
 
175
175
  - **参考:** wikipedia [控えめなJavaScript#動作とマークアップの分離](https://ja.wikipedia.org/wiki/%E6%8E%A7%E3%81%88%E3%82%81%E3%81%AAJavaScript#%E5%8B%95%E4%BD%9C%E3%81%A8%E3%83%9E%E3%83%BC%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%AE%E5%88%86%E9%9B%A2)
176
176
 
177
- HTML要素の属性である `onclick` や `onchange` はイベント属性と呼ばれますが、MDNのイベント属性の説明には、以下のように書かれています。
177
+ HTML要素の属性である `onclick` や `onchange` はイベント属性と呼ばれますが、MDNのイベント属性の説明には、以下のように、使用を非推奨とする旨が書かれています。
178
178
 
179
179
  > 警告: これらの属性を使うことは避けるべきです。これは HTML を巨大化し可読性を下げます。情報と振る舞いの関心事が正しく分離されておらず、発見が困難なバグを生み出します。その上に、Event 属性の使い方はほとんどの場合、Window オブジェクト上のグローバル関数にスクリプトを晒す原因になります。これはグローバルの名前空間を汚染します。
180
180
 

14

テキスト修正

2019/10/30 00:33

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -75,7 +75,7 @@
75
75
 
76
76
  ### 追記1
77
77
 
78
- 上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、何らかの追加、修正をする必要がないものになっています。以下はテーブルの行を7行に増やまし、javascriptのコードには何も手を加えていないです。
78
+ 上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、何らかの追加、修正をする必要がないものになっています。以下は、上記のHTMLのテーブルの行を単に7行にしただけで、javascriptのコードには何も手を加えていないです。
79
79
 
80
80
  - **テーブルの行を7行にした:** [https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010](https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010)
81
81
 

13

テキスト修正

2019/10/30 00:22

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -91,7 +91,7 @@
91
91
  ```html
92
92
  <input type="button" value="+" onClick="count_up_btn1()">
93
93
  ```
94
- のように、`input`要素の`onclick`属性にスクリプトを直接書くというそのまま使って、かつコードをまとめる例を挙げておきます。
94
+ のように、`input`要素の`onclick`属性にスクリプトを直接書くというそのまま使いつつ、かつコードをまとめる例を挙げておきます。
95
95
 
96
96
  修正方法としては、上記を
97
97
  ```html

12

テキスト修正

2019/10/29 23:28

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -174,7 +174,7 @@
174
174
 
175
175
  - **参考:** wikipedia [控えめなJavaScript#動作とマークアップの分離](https://ja.wikipedia.org/wiki/%E6%8E%A7%E3%81%88%E3%82%81%E3%81%AAJavaScript#%E5%8B%95%E4%BD%9C%E3%81%A8%E3%83%9E%E3%83%BC%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%AE%E5%88%86%E9%9B%A2)
176
176
 
177
- HTML要素の属性である `onclick` や `onchange` はEvent 属性と呼ばれますが、MDNのEvent属性の説明には、以下のように書かれています。
177
+ HTML要素の属性である `onclick` や `onchange` はイベント属性と呼ばれますが、MDNのイベント属性の説明には、以下のように書かれています。
178
178
 
179
179
  > 警告: これらの属性を使うことは避けるべきです。これは HTML を巨大化し可読性を下げます。情報と振る舞いの関心事が正しく分離されておらず、発見が困難なバグを生み出します。その上に、Event 属性の使い方はほとんどの場合、Window オブジェクト上のグローバル関数にスクリプトを晒す原因になります。これはグローバルの名前空間を汚染します。
180
180
 

11

テキスト修正

2019/10/29 23:21

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -156,4 +156,29 @@
156
156
  });
157
157
  }
158
158
  ```
159
- - **動作確認用CodePen: ** [https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010](https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010)
159
+ - **動作確認用CodePen: ** [https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010](https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010)
160
+
161
+ ### 追記3
162
+
163
+ ご質問にある、下記のHTML
164
+ ```html
165
+ <input type="button" value="+" onClick="count_up_btn1()">
166
+ ```
167
+ のように、HTML要素の`onclick`などの属性に直接スクリプトを書くことで、イベントを処理させる書き方に対して、この回答の冒頭に書いたコードの下記の部分
168
+ ```javascript
169
+ btn.addEventListener('click', () => {
170
+  ・・・
171
+ });
172
+ ```
173
+ のように、プログラムの中でイベントハンドラを設定する書き方は、**控えめなJavaScript**(Unobtrusive JavaScript)と呼ばれることがあります。
174
+
175
+ - **参考:** wikipedia [控えめなJavaScript#動作とマークアップの分離](https://ja.wikipedia.org/wiki/%E6%8E%A7%E3%81%88%E3%82%81%E3%81%AAJavaScript#%E5%8B%95%E4%BD%9C%E3%81%A8%E3%83%9E%E3%83%BC%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97%E3%81%AE%E5%88%86%E9%9B%A2)
176
+
177
+ HTML要素の属性である `onclick` や `onchange` はEvent 属性と呼ばれますが、MDNのEvent属性の説明には、以下のように書かれています。
178
+
179
+ > 警告: これらの属性を使うことは避けるべきです。これは HTML を巨大化し可読性を下げます。情報と振る舞いの関心事が正しく分離されておらず、発見が困難なバグを生み出します。その上に、Event 属性の使い方はほとんどの場合、Window オブジェクト上のグローバル関数にスクリプトを晒す原因になります。これはグローバルの名前空間を汚染します。
180
+
181
+ > これらの属性が魅力的で簡単に使うことができたとしても、これを使うのは避けるべきです。代わりに、イベントリスナーを追加する為には EventTarget.addEventListener() 関数を使ってください。
182
+
183
+
184
+ - 以上、 MDN [Event 属性](https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Event_attributes) より引用

10

テキスト修正

2019/10/29 23:14

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -73,7 +73,7 @@
73
73
 
74
74
  参考になれば幸いです。
75
75
 
76
- ### 追記
76
+ ### 追記1
77
77
 
78
78
  上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、何らかの追加、修正をする必要がないものになっています。以下はテーブルの行を7行に増やしましたが、javascriptのコードには何も手を加えていないです。
79
79
 
@@ -97,7 +97,7 @@
97
97
  ```html
98
98
  <input type="button" value="+" onclick="count(this)">
99
99
  ```
100
- のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるようにします。以下、その一例です。
100
+ のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるようにします。以下、その一例です。(先の追記1に書いた意図と同じく、`one`, `two`, `three` を使わないようにもしています。)
101
101
 
102
102
  ```html
103
103
  <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">

9

テキスト修正

2019/10/29 15:36

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -91,7 +91,7 @@
91
91
  ```html
92
92
  <input type="button" value="+" onClick="count_up_btn1()">
93
93
  ```
94
- のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめるコード例を挙げておきます。
94
+ のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめる例を挙げておきます。
95
95
 
96
96
  修正方法としては、上記を
97
97
  ```html

8

テキスト修正

2019/10/29 15:19

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -91,11 +91,13 @@
91
91
  ```html
92
92
  <input type="button" value="+" onClick="count_up_btn1()">
93
93
  ```
94
- のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめるコード例を挙げておきます。この場合に、テーブルの行が増えてもjavascriptのコードには変更追加が必要のないものにする(すなわち、`one`, `two`, `three` を使わないようにする)には、上記を
94
+ のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめるコード例を挙げておきます。
95
+
96
+ 修正方法としては、上記を
95
97
  ```html
96
98
  <input type="button" value="+" onclick="count(this)">
97
99
  ```
98
- のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるといコードなるかと思います。以下、その一例です。
100
+ のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるうにます。以下、その一例です。
99
101
 
100
102
  ```html
101
103
  <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">
@@ -138,6 +140,10 @@
138
140
  </tr>
139
141
  </table>
140
142
  ```
143
+
144
+ 以下は、 上記のボタンクリック時に使用する関数`count(button)` の一例です。
145
+
146
+
141
147
  ```javascript
142
148
  function count(button) {
143
149
  const diff = +`${button.value}1`;

7

テキスト修正

2019/10/29 14:45

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -91,7 +91,7 @@
91
91
  ```html
92
92
  <input type="button" value="+" onClick="count_up_btn1()">
93
93
  ```
94
- のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめて、テーブルの行が増えてもjavascriptのコードには変更追加が必要のないものにする(すなわち、`one`, `two`, `three` を使わないようにする)には、上記を
94
+ のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめるコード例を挙げおきます。この場合に、テーブルの行が増えてもjavascriptのコードには変更追加が必要のないものにする(すなわち、`one`, `two`, `three` を使わないようにする)には、上記を
95
95
  ```html
96
96
  <input type="button" value="+" onclick="count(this)">
97
97
  ```

6

テキスト修正

2019/10/29 14:26

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -95,7 +95,7 @@
95
95
  ```html
96
96
  <input type="button" value="+" onclick="count(this)">
97
97
  ```
98
- のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、これに処理させるというコードになるかと思います。以下、その一例です。
98
+ のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、どのボタンがクリックされてもこれに処理させるというコードになるかと思います。以下、その一例です。
99
99
 
100
100
  ```html
101
101
  <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">

5

テキスト修正

2019/10/29 14:16

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -83,4 +83,71 @@
83
83
 
84
84
  - `one`, `two`, `three`, ... という id や変数を使わないようにすること
85
85
 
86
- が、リファクタリングしていく際の指針のひとつになります。
86
+ が、リファクタリングしていく際の指針のひとつになります。
87
+
88
+ ### 追記2
89
+
90
+ hj_zebraさんのご質問にある元のコードで、HTMLの下記の部分
91
+ ```html
92
+ <input type="button" value="+" onClick="count_up_btn1()">
93
+ ```
94
+ のように、`input`要素の`onclick`属性にスクリプトを直接書くという方法はそのまま使って、かつコードをまとめて、テーブルの行が増えてもjavascriptのコードには変更追加が必要のないものにする(すなわち、`one`, `two`, `three` を使わないようにする)には、上記を
95
+ ```html
96
+ <input type="button" value="+" onclick="count(this)">
97
+ ```
98
+ のようにして、クリックされたボタンを引数にとる関数`count(button)` を作っておいて、これに処理させるというコードになるかと思います。以下、その一例です。
99
+
100
+ ```html
101
+ <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">
102
+ <tr>
103
+ <th>種類</th>
104
+ <th>プラス</th>
105
+ <th>マイナス</th>
106
+ <th>合計<br>回数</th>
107
+ <th>残り<br>回数</th>
108
+ </tr>
109
+ <tr>
110
+ <td align="center">1</td>
111
+ <td align="center"><input type="button" value="+" onclick="count(this)" /></td>
112
+ <td align="center"><input type="button" value="-" onclick="count(this)" /></td>
113
+ <td align="center"><span>0</span>回</td>
114
+ <td></td>
115
+ </tr>
116
+ <tr>
117
+ <td align="center">2</td>
118
+ <td align="center"><input type="button" value="+" onclick="count(this)" /></td>
119
+ <td align="center"><input type="button" value="-" onclick="count(this)" /></td>
120
+ <td align="center"><span>0</span>回</td>
121
+ <td></td>
122
+ </tr>
123
+ <tr>
124
+ <td align="center">3</td>
125
+ <td align="center"><input type="button" value="+" onclick="count(this)" /></td>
126
+ <td align="center"><input type="button" value="-" onclick="count(this)" /></td>
127
+ <td align="center"><span>0</span>回</td>
128
+ <td></td>
129
+ </tr>
130
+ </table>
131
+ <br>
132
+ <table border="1"cellspacing="0" cellpadding="5" bordercolor="black">
133
+ <tr>
134
+ <th>合計<br>回数</th>
135
+ </tr>
136
+ <tr>
137
+ <td align=center><span id="total">0</span>回</td>
138
+ </tr>
139
+ </table>
140
+ ```
141
+ ```javascript
142
+ function count(button) {
143
+ const diff = +`${button.value}1`;
144
+ const spans = [
145
+ document.getElementById('total'),
146
+ button.closest('tr').querySelector('span')
147
+ ];
148
+ spans.forEach(span => {
149
+ span.textContent = +span.textContent + diff;
150
+ });
151
+ }
152
+ ```
153
+ - **動作確認用CodePen: ** [https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010](https://codepen.io/jun68ykt/pen/OJJjYdG?editors=1010)

4

テキスト修正

2019/10/29 13:59

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -75,12 +75,12 @@
75
75
 
76
76
  ### 追記
77
77
 
78
- 上記のJavascriptのコードは、テーブルの行が増えても、何らかの追加、修正をする必要がないものになっています。以下はテーブルの行を7行に増やしましたが、JavaScriptのコードのほう何も手を加えていないです。
78
+ 上記の回答に挙げたjavascriptのコードは、テーブルの行が増えても、何らかの追加、修正をする必要がないものになっています。以下はテーブルの行を7行に増やしましたが、javascriptのコードは何も手を加えていないです。
79
79
 
80
80
  - **テーブルの行を7行にした:** [https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010](https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010)
81
81
 
82
- ご質問に挙げられている元のコードを、テーブルの行が何行になっても追加、修正する必要がないものにするには、
82
+ ご質問に挙げられている元のjavascriptのコードを、テーブルの行が何行になっても追加、修正する必要がないものにするには、
83
83
 
84
84
  - `one`, `two`, `three`, ... という id や変数を使わないようにすること
85
85
 
86
- が、リファクタリングの目標のひとつになります。
86
+ が、リファクタリングしていく際指針のひとつになります。

3

テキスト修正

2019/10/29 13:06

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -71,4 +71,16 @@
71
71
  - **動作確認用 CodePen: ** [https://codepen.io/jun68ykt/pen/mddMGbV?editors=1010](https://codepen.io/jun68ykt/pen/mddMGbV?editors=1010)
72
72
 
73
73
 
74
- 参考になれば幸いです。
74
+ 参考になれば幸いです。
75
+
76
+ ### 追記
77
+
78
+ 上記のJavascriptのコードは、テーブルの行が増えても、何らかの追加、修正をする必要がないものになっています。以下はテーブルの行を7行に増やしましたが、JavaScriptのコードのほうは、何も手を加えていないです。
79
+
80
+ - **テーブルの行を7行にした:** [https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010](https://codepen.io/jun68ykt/pen/BaadEmw?editors=1010)
81
+
82
+ ご質問に挙げられている元のコードを、テーブルの行が何行になっても追加、修正する必要がないものにするには、
83
+
84
+ - `one`, `two`, `three`, ... という id や変数を使わないようにすること
85
+
86
+ が、リファクタリングの目標のひとつになります。

2

テキスト修正

2019/10/29 12:25

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -48,17 +48,22 @@
48
48
  document.addEventListener('DOMContentLoaded', function() {
49
49
 
50
50
  const totalSpan = document.getElementById('total');
51
-
52
- [...document.querySelectorAll('table:first-of-type tr')].forEach(row => {
51
+ const rows = [...document.querySelectorAll('table:first-of-type tr')];
52
+
53
+ rows.forEach((row, rowIndex) => {
54
+ if (rowIndex === 0) return;
55
+
53
56
  const counterSpan = row.querySelector('span');
54
- [...row.querySelectorAll('input')].forEach((btn, btnIndex) => {
57
+ const buttons = [...row.querySelectorAll('input')];
58
+
59
+ buttons.forEach((btn, btnIndex) => {
55
60
  btn.addEventListener('click', () => {
56
61
  [counterSpan, totalSpan].forEach(span => {
57
62
  span.textContent = +span.textContent + (btnIndex ? -1 : 1);
58
63
  });
59
64
  });
60
- });
65
+ });
61
- });
66
+ });
62
67
 
63
68
  });
64
69
  ```

1

テキスト修正

2019/10/29 08:37

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -52,7 +52,7 @@
52
52
  [...document.querySelectorAll('table:first-of-type tr')].forEach(row => {
53
53
  const counterSpan = row.querySelector('span');
54
54
  [...row.querySelectorAll('input')].forEach((btn, btnIndex) => {
55
- btn.addEventListener('click', e => {
55
+ btn.addEventListener('click', () => {
56
56
  [counterSpan, totalSpan].forEach(span => {
57
57
  span.textContent = +span.textContent + (btnIndex ? -1 : 1);
58
58
  });