jQueryでのpropとattrの違い

5864 ワード

jQueryでhtmlタグのプロパティを取得するのはattrメソッドだと思っていましたが、今日たまたま1つの文章を見て、もう1つのpropメソッドがあることに気づき、2つのメソッドの違いを調べたいと思っていました.結局本当に穴を掘った.
まず実験をして、以下のコードをhtmlファイルに保存して、走ります(このブログを書く時jQueryバージョンは1.9.1です)
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html>
<head>
  <style>
  p { margin: 20px 0 0 }
  b { color: blue; }
</style>
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>

<input id="check1" type="checkbox" checked="checked">
<label for="check1">Check me</label>
<p></p>

<script>
$("input").change(function() {
  var $input = $(this);
  $("p").html(".attr('checked'): <b>" + $input.attr('checked') + "</b><br>"
              + ".prop('checked'): <b>" + $input.prop('checked') + "</b><br>"
              + ".is(':checked'): <b>" + $input.is(':checked') ) + "</b>";
}).change();
</script>

</body>
</html>

これはjQuery公式ドキュメントのpropメソッドの一例であり,propとattrの違いを示している.まず結果を言います.
JavaScript
1
2
attr('checked')    //   checkbox    ,    'checked',    true false
prop('checked')    //   checkbox     true false

どうしてこんな結果になったの?jQueryはなぜattrとpropの2つの類似の方法を提供するのですか?これはhtmlから言わなければなりません.
htmlのattributeとproperty
中国語ではこの2つの語の差は多くないが、htmlではこの定義に厳しい違いがある.まず大まかに説明します.
attributeはhtmlテキストレベルで、htmlを書くときに見られるkey=「value」はattributeです.htmlテキストが変更されない限り、html要素定義時の値です.
propertyはdomレベルであり,オリジナルJavaScript関数で取得したdomオブジェクトの属性として理解できる.domツリーの操作によって変わりますあるpropertyはdomオブジェクトにおけるattributeのプレゼンテーションです.だからpropertyとattributeには一定の交差がある.
例を見てみましょう.
HTML
1
<input type="checkbox" id="cb" class="cb" name="key" checked="checked"/>

これはcheckboxで、デフォルトはチェックされた状態です.そのattributeにはid,type,class,name,checkedがあります.これらのattributeの値は変更されません.チェックを解除しても、そのcheckedプロパティは「checked」です.
domレベルでは、id、type、name、checkedともに同名のpropertyがあります.classというattributeはpropertyに対応するclassNameと呼ばれています.またdom要素としてnodeNameというpropertyもあります.上のcheckbox要素のdomオブジェクトはJavaScriptで取得できます.propertyはJavaScriptのdomオブジェクトのプロパティと見なすことができます.
JavaScript
1
2
3
4
5
var el = document.getElementById('cb');
el.className   // "cb"        property    attribute           。
el.class       // undefined
el.nodeName    // "INPUT"     property      attribute   ,   dom  
el.checked     // true              "checked"

これらを理解すれば,jQueryのpropとattrの方法の違いを理解することは難しくない.しかし、まだ終わっていません.
jQueryのattrとprop
html仕様を遵守するために、jQueryはattributeとpropertyに対してそれぞれパッケージ方法attrとpropを提供した.しかし、propはjQuery 1.6バージョンなので導入され、jQuery 1.9以前のバージョンは古いコードの互換性の問題を考慮するためにattrとpropの境界が少し曖昧になっていた.
やはり上のcheckboxの例を取って、jQueryの中の各バージョンの違いを見て、まずcheckedの属性を持って実験をします
JavaScript
1
2
3
4
5
$('.cb').prop("checked")    // true     checkbox       
$('.cb').attr("checked")    // (pre-1.6) true     checkbox     
                            // (1.6) "checked"      checkbox     ,    
                            // (1.6.1 - 1.8) "checked"     checkbox       ,              
                            // (1.9.1) "checked"      checkbox     , 1.6  

次に、attrとpropが取得した値に違いがあるかどうかを確認します.
JavaScript
1
2
3
$('.cb').prop('name', "aaa")   //      prop  attr          
$('.cb').prop('name')          // "aaa"            
$('.cb').attr('name')          // "aaa"    

ここには何の違いもないのが見えますが、なぜですか?attributeはhtmlテキストの変更を対象としているため、以上のコード、nameを変更すると、対応するhtmlテキストも変化します(開発ツールで見ることができます).ここでattrとpropは変更後の値を取得します.
最後に、いつどのような方法が適しているかをまとめます.
propertyを変えるとhtmlが変わるので、propでもattrでも構いません.ほとんどのpropertyは、type、name、srcなどの列に属します.JavaScriptでpropertyを変更してから開発ツールでhtmlが変わったかどうかを見ることができます.
propertyを変更してもhtmlは変更されません.prop、またはjQueryがこの属性に特化して提供する方法の例を挙げると、テキストボックスのvalue属性は、ユーザー入力やJavaScriptで変更することができ、propもvalも正しい値を得ることができますが、valを優先的にお勧めします.この場合attrが返す値はまったく間違っています.
attribute対応のpropertyではなく、nodeNameなどのpropを使用するのに適しています.
true/falseの意味を表すattributeは、checked、disabledなどのpropで判断するのに適しています.
リファレンスドキュメント
jQuery: Test/check if checkbox is checkedこの文章はcheckboxが選択されたかどうかを判断する方法をいくつか挙げており、例が多い.
HTML: The difference between attribute and propertyこの文章ではattributeとpropertyの違いについて述べたが、attributeの定義は正しくなく、attributeはhtml定義時の初期状態に準拠するのではなく、htmlテキストの変化と常に同期している.
jQuery API: prop公式APIでは、propに参加する理由と、異なるバージョンでの違いを説明しています.
http://darkbaby123.github.io/blog/2013/02/19/jquery-prop-and-attr/