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

回答編集履歴

2

jsfiddleのサンプル追加

2017/08/02 11:49

投稿

think49
think49

スコア18194

answer CHANGED
@@ -27,6 +27,8 @@
27
27
  required 属性は「反映型IDL属性 (Reflecting content attributes)」の為、`required` プロパティと同様の結果を得ることが出来ます。
28
28
  ただし、他所からIDL属性が変更された場合は属性値に空文字(falsy)がセットされる為、注意が必要です。
29
29
 
30
+ - [requiredプロパティとrequired属性 - JSFiddle](https://jsfiddle.net/Lt3emgc1/1/)
31
+
30
32
  ```HTML
31
33
  <form>
32
34
  <input type="text" />

1

仕様を勘違いしていた為、本文を大幅に変更しました

2017/08/02 11:49

投稿

think49
think49

スコア18194

answer CHANGED
@@ -1,10 +1,32 @@
1
- ### requiredプロパティとrequired属性
1
+ **(2017/08/02 20:47追記) 仕様を勘違いしていた為、本文を大幅に変更しました。**
2
2
 
3
- HTMLの required 属性は明示的に属性値を変更しなければ、変わる事はありません。
3
+ ### required 属性
4
- 動的に `required` プロパティのステータスが変更された場合、「required プロパティ」には反映されますが、「required 属性」には反映されません。
5
4
 
6
- - [requiredプロパティとrequired属性 - JSFiddle](https://jsfiddle.net/Lt3emgc1/)
5
+ - [4.10.5 The input element - HTML Standard](https://html.spec.whatwg.org/multipage/input.html#dom-input-required)
7
6
 
7
+ > The accept, alt, max, min, multiple, pattern, placeholder, required, size, src, and step IDL attributes must reflect the respective content attributes of the same name. The dirName IDL attribute must reflect the dirname content attribute. The readOnly IDL attribute must reflect the readonly content attribute. The defaultChecked IDL attribute must reflect the checked content attribute. The defaultValue IDL attribute must reflect the value content attribute.
8
+
9
+ (意訳)
10
+ accept、alt、max、min、multiple、pattern、placeholder、required、size、src、およびstep IDL属性は、同じ名前のそれぞれのコンテンツ属性を[反映(reflect)](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflect)しなければならない(MUST)。
11
+
12
+ 反映(reflect)は後述の「反映型IDL属性 (Reflecting content attributes)」を参照しています。
13
+
14
+ ### 反映型IDL属性 (Reflecting content attributes)
15
+
16
+ - [2.6.1 Reflecting content attributes in IDL attributes - HTML Standard](https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes)
17
+
18
+ > If a reflecting IDL attribute is a boolean attribute, then on getting the IDL attribute must return true if the content attribute is set, and false if it is absent. On setting, the content attribute must be removed if the IDL attribute is set to false, and must be set to the empty string if the IDL attribute is set to true. (This corresponds to the rules for boolean content attributes.)
19
+
20
+ (意訳)
21
+ 反映型IDL属性(Reflecting content attributes)が boolean 属性の場合、IDL属性を取得すると、content属性が設定されている場合はtrueを返し、存在しない場合はfalseを返さなければならない(MUST)。
22
+ IDL属性がfalseに設定されている場合はコンテンツ属性を削除し、IDL属性がtrueに設定されている場合は空の文字列に設定しなければならない(MUST)。
23
+ (これは [boolean content 属性](https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#boolean-attribute)のルールに相当する。)
24
+
25
+ ### まとめ
26
+
27
+ required 属性は「反映型IDL属性 (Reflecting content attributes)」の為、`required` プロパティと同様の結果を得ることが出来ます。
28
+ ただし、他所からIDL属性が変更された場合は属性値に空文字(falsy)がセットされる為、注意が必要です。
29
+
8
30
  ```HTML
9
31
  <form>
10
32
  <input type="text" />
@@ -13,15 +35,50 @@
13
35
  <script>
14
36
  'use strict';
15
37
  var input = document.querySelector('input[type=text]');
38
+
39
+ console.log(input.getAttribute('required')); // null (required 属性は存在しない)
40
+ console.log(input.attributes.getNamedItem('required')); // null (required 属性は存在しない)
16
41
  input.required = true;
17
- console.log(input.required); // true
42
+ console.log(input.required); // true (反映型IDL属性の規定によって、required 属性が作成され、値は "" になる)
18
- console.log(input.getAttribute('required')); // ""
43
+ console.log(input.getAttribute('required')); // "" (required 属性は存在する)
44
+ console.log(input.attributes.getNamedItem('required')); // [object Attr] required="" (required 属性は存在する)
19
45
  </script>
20
46
  ```
21
47
 
22
- ### required属性を使うために
48
+ つまり、次のコードの評価値常に等価となります。
23
49
 
50
+ ```JavaScript
51
+ input.required;
52
+ input.getAttribute('required') !== null;
24
- 常に required 属性を操作するならば、この問題は回避できますが、他のコードから `required`プロパティが操作される事はあり得ます。
53
+ Boolean(input.attributes.getNamedItem('required'));
25
- 従って、required 属性を使うためには「**required は属性操作系APIで操作しなければならない**」というコーディング規約を作る必要があるわけですが、そこにコストをかける意味はないと私は思います。
54
+ ```
26
55
 
56
+ `if` 文に適用すると、次のコードになります。
57
+
58
+ ```JavaScript
59
+ // good
60
+ if (input.required) {
61
+ // 処理
62
+ }
63
+
64
+ // good
65
+ if (input.getAttribute('required') !== null) {
66
+ // 処理
67
+ }
68
+
69
+ // bad
70
+ if (input.getAttribute('required')) {
71
+ // 処理
72
+ }
73
+
74
+ // good
75
+ if (input.attributes.getNamedItem('required')) {
76
+ // 処理
77
+ }
78
+ ```
79
+
80
+ 仕様上、`getAttribute` や `attributes.getNamedItem` で required 属性を参照する事に問題はありません。
81
+ が、`getAttribute` だけは直観的でない為、直観的でシンプルな `required` プロパティが使われる傾向はあると思います。
82
+ 後は使う人が判断する事になります。
83
+
27
84
  Re: maisumakun さん