jQuery 1.6.1 ~ 1.6.4 での変更箇所の自分なりのまとめ

jQuery 1.6.1 , 1.6.2 , 1.6.3 , 1.6.4 のリリースノートを読んで、自分なりにまとめました。 といっても、1.6.2 と 1.6.4 はバグ修正がメインでした。 誤訳による勘違いなどもあると思われるので、 読まれる際はご注意を。(※ページをそのまま訳したわけではありません)
箇条書きにすると以下のような感じ:

  • 1.6.0で失った.attr()の後方互換性の回復[1.6.1]
    • 何が変わったのか
    • 推奨される使用方法のまとめ
  • XSS 攻撃ベクトルの対策[1.6.3]
  • requestAnimationFrameの使用中止[1.6.3]

1.6.0で失った.attr()の後方互換性の回復[1.6.1]

1.6.0 で、DOM 属性への処理とDOM プロパティへの処理を .attr()と新規導入の.prop()に 分離しました。 そのため.attr()に後方互換性の問題が 発生したのですが、jQuery のコミュニティが混乱したようで、 1.6.1 で修正されたそうです。

1.5.2 から 1.6.1 に更新すれば属性まわりのコードを 変更しなくてもよいことになります。

1.6.0 より前のバージョンでは属性とプロパティを一つのメソッド (.attr())で処理していて、バグがたくさんあって メンテナンスが大変だったそうです。そのためなのか分かりませんが、 1.6.0 で属性とプロパティとの間のあいまいさを無くすため、 .attr()と新規導入の.prop()に 処理を分離しました。そのため、1.6.0 より前のバージョンで 動いていた以下のようなコードが

// http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/ での例です
$(":checkbox").attr("checked", true);
$("option").attr("selected", true);
$("input").attr("readonly", true);
$("input").attr("disabled", true);

if ( $(":checkbox").attr("checked") ) {
  /* 何かする */
}

1.6.0 では正しく動かなくなりました。 1.6.1 では修正され正しく動きます。

動くなら、これからも.attr()だけ使えば良く、 .prop()はいらないんじゃ、という感じがしますが、 一応使い分けることを推奨しています。以下は .attr().prop()の 推奨される使い分けの解説です。

何が変わったのか

下のコードは、.prop()を使うことが推奨される .attr()の使用例です。

// http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/ での例です
$(window).attr…
$(document).attr…
$(":checkbox").attr("checked", true);
$("option").attr("selected", true);

これらのコードは次のように.prop()を使うことが 推奨されます。

// http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/ での例です
$(window).prop…
$(document).prop…
$(":checkbox").prop("checked", true);
$("option").prop("selected", true);

windowdocumentは属性を 持たず、(locationreadyStateの ような)プロパティを持ちます。そのため、 .prop()か、素の JavaScript で処理すべきです。 1.6.0 ではwindowdocument.attr()を使えなかったのですが 1.6.1 では.prop()に処理を任せるようになったので ちゃんと動きます。でも.prop()が推奨されます。

checkedselectedなどの boolean 型の属性は特殊な扱いを受けます。

<input type="checkbox" checked="checked">

boolean 型の属性はデフォルト値か初期値がページの読み込み時に 設定されるだけで、現在値を追跡しません。上の場合、 ページが読み込まれるとき、属性checkedは 初期値"checked"が設定されます。チェックボックスを クリックしても値は更新されません。boolean 型の属性は 初期値を保持するためだけにブラウザに使用されます。

一方、boolean 型の属性と同名のプロパティは初期値に その属性を反映した値を取り、以降、「現在」値を追跡します。 上の場合、チェックボックスをクリックすると値が更新されます。 1.6.0 では、

// http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/ での例です
$(":checkbox").attr("checked", true);

のように属性checkedを設定しても、 初期値を設定したに過ぎず、 チェックボックスはチェックするには以下のように プロパティを設定しなければなりません。

// http://blog.jquery.com/2011/05/12/jquery-1-6-1-released/ での例です
$(":checkbox").get(0).checked = true;
// $(":checkbox:first").prop("checked", true); と同じ

1.6.0 がリリースされてすぐ、jQuery チームは、 ページを読み込むときにブラウザが使うだけの boolean 型の属性を設定できても特に役に立たない、 ということを理解したそうで、1.6.1 で boolean 型のプロパティを .attr()で設定・取得できるようになりました。
以下のboolean 型の属性/プロパティが.attr()で 動的に設定・取得できます。

autofocus, autoplay, async, checked, controls, defer, disabled,
hidden, loop, multiple, open, readonly, required, scoped, selected

上のリストの属性/プロパティは.attr()内部で フックされ、取得はプロパティ、設定は属性・プロパティに 行われます。

それでもなお boolean 型の属性/プロパティを設定する時は .prop()を使うことを推奨しています。 しかし、.prop()を使わなくても動くようになったので コードを変更しなければならない、ということはなくなりました。

以下は 取得・設定するときに推奨されるメソッドを示した 属性とプロパティのリストです。 これは推奨使用ですが、.attr()は 属性ならどの場面でも動くでしょう。 .attr()の列で、○も△も付いてない DOM 要素の プロパティがありますが、それらは.prop()でしか 正しく動かないことに注意してください。

Attribute/Property.attr().prop()
accesskey
align
async
autofocus
checked
class
contenteditable
defaultValue
draggable
href
id
label
location *
multiple
nodeName
nodeType
readOnly
rel
selected
selectedIndex
src
style
tabindex
tagName
title
type
width **

* 例えば、window.location
** .width()で必要な場合

.attr().prop()も 値(value)を取得・設定するのに使うべきではありません。 .val()を代わりに使いましょう。 (1.6.0 より前にしていたように、 .attr("value", "samevalue")を使っても 動くでしょうが)

推奨される使用方法のまとめ

.prop()は boolean 型の属性/プロパティや、 (window.locationのような)html 内に存在しない プロパティに対して使うべきです。 他の属性(html 内で見られる属性)に対しては全て .attr()で操作できるし、操作し続けるべきです。

XSS 攻撃ベクトルの対策[1.6.3]

要素の選択にwindow.location.hashを 利用している場合(例えば$(location.hash))、 ページにスクリプトを挿入される可能性があるという レポートが報告され、その対策が講じられました。

セレクタ文字列の先頭に"#"がある場合、 HTML タグを(そのため当然スクリプトも)含むことが できなくなりました。(例えば$("#<script>…")) 詳細は そのレポート をご覧下さい。

requestAnimationFrameの使用中止[1.6.3]

タブが非表示の時のrequestAnimationFrameの 振舞い方がおかしく、このAPIの使用を将来のバージョンまで 中止にしたそうです。  jQuery のアニメ機能の実行方法には影響が無いようです。

スポンサードリンク