jqueryのattrとprop(とdataとvalとhtmlとかつまり属性とかの取得)の使い分け一覧

  • 69
    Like
  • 2
    Comment
More than 1 year has passed since last update.

最初に

  • attrpropの使い分けがわからないと言われたので、誰でも使い分けができるようになる一覧を作りました。

  • 基本的にはpropで取得できるものはpropで、そうじゃないものはattrで、と思っていたのですが、data-*valueまでそれで取得していたので、思ったよりもが根が深いなと思った次第です。

(追記)data属性に対する扱いについて

data-*属性には、用途が2種類あります。

  • HTML5としてのカスタム属性(とそれを利用した関連技術)
  • jQueryのdata()メソッドのための初期値

前者はそれを利用した有名どころではBootstrap(TwitterBootstrap)がなどがありますが、
CSSの属性セレクタとしても使えるので、別にBootstrapに限った話ではなく、普通に使用している人もいるかと思います。

問題は後者の方で、ここで「初期値」と書いたり、追記前の記事で「取得しようとしているのは」と前置きしたことの理由にもなるのですが、data()ではgetでattributeから読みだすことはできても、setでattributeに対して変更することはできません。また、attributeから読みだすのも最初の1回のみです。

そのため、data-*だからと言って何でもかんでもdata()で読みだしていると、動的な変更に追従できず、また、getができるんだからsetもdata()でいいんだな、と思うと、HTML5としてのカスタム属性の動作に期待している場合は、期待通りの動作になりません。

判断一覧

取得しようとしているのはdata-*ではありませんか?

それはHTMLのカスタム属性として使用している属性ですか?

  • attr()を使用してください。getもsetもです。
  • 参照専用であればgetだけdata()を使うこともできますが、止めた方が良いです。なぜなら必要なのはattributeだからです。

それはHTMLのカスタム属性として使用してない属性ですか?

  • data()を使用してください。

取得しようとしているのはclassではありませんか?

  • hasClass()で事足りませんか?
  • その後やりたいことによってはadd/removeClass()の方が適しているかもしれません。

特定クラス名がセットされているか、ではなく、クラス名そのものが欲しい場合は?

  • そんな文字列をclassで賄おうとするその思考を考え直してください。
  • data-xxxで別属性として定義してください。

取得しようとしているのはvalueではありませんか?

  • val()を使用してください。

textareaに入力された値が必要ですか?

  • その場合もval()を使用してください。
  • タグの中だからってtext()html()を使う必要はありません。

checkboxやradiobuttonがチェックされているかどうかを知りたいですか?

  • prop('checked')を使ってください。attr()"checked"と比較するのはギルティーです。

checkboxやradiobuttonをチェックしたいor外したいですか?

  • prop('checked', true|false)を使ってください。attr()や、ましてやremoveAttr()などは論外です。

disabledかどうかを知りたいですか?

  • prop('disabled')を使ってください。attr()"disabled"と比較するのはギルティーです。

disabledにしたいor外したいですか?

  • prop('disabled', true|false)を使ってください。attr()や、ましてやremoveAttr()などは論外です。

aタグにおけるhrefや、imgにおけるsrc等のアドレスのパスについて、

絶対パスが必要ですか?

  • prop()を使ってください。

相対パスが必要ですか?

  • attr()を使ってください。
  • ただし、htmlに絶対パスとして記述されている場合は絶対パスになります。

上記以外の属性を取得したい

それはHTML標準の属性ですか?

  • prop()を使ってください。

それはHTML標準ではない、勝手に命名した属性ですか?

  • attr()を使ってください。
  • data-xxxxとした上で、data()を使ってください。

そもそも

なんで、attrpropertiesを操作するサンプルコードが巷にあふれているかというと、昔はできたというか、昔はattrしか無かった(propメソッド存在しなかった)んじゃよ、と思うjqueryおじさんであった。

昔々...
propが実装されたのは1.6からで、それまではattributepropertiesはjquery上で明確に分かれてはいませんでした。
そのため、当時は皆propertiesを操作するためにもattrを使っていたのですが、やはり分けないとまずかろうということで、1.6.0リリースによって、propが実装され、attributepropertiesは明確に区別されるようになりました。ところが、attrpropertiesをどうのこうのしていた(するしかなかった)巷にあふれる大半のソースは最新のjqueryでは正しく動作しなくなり大きな混乱を招いた結果、後方互換を持った1.6.1がリリースされ、それからしばらくはattrdisabled等の設定を変更できました。

完全にできなくなったのは1.9からでした。
そのため、1.9より以前に書かれた説明ではattrpropertiesを操作しているコードがあります。
それは当時では間違いではなかった、という話です。
乱暴な話、view(html)を自前で用意するのであれば、今ではattrを使わなければいけない個所は1つもないはずです。