3.0正式版がリリースされたので、新しい記事を書きました 【翻訳まとめ】jQuery 3.0 アップグレードガイド
tl;dr
- jQuery 3.0 alphaがリリース
-
.hide()
と.show()
に後方互換性のない変更あり(注意!) - jQuery.DeferredがよりPromises/A+に準拠
-
.width()
と.height()
が小数値を返せるように - 非推奨の
.load
,.unload
,.error
や、ajaxの.success()
,.error()
,.complete()
が廃止 -
requestAnimationFrame
の復活
はじめに
2015/7/13にjQuery 3.0 alphaがリリースされました。
http://blog.jquery.com/2015/07/13/jquery-3-0-and-jquery-compat-3-0-alpha-versions-released/
この記事はこのリリースノートの翻訳まとめです。
一部わかりやすいように言い換えたり、補足したり、省略したりしています。
概要
jQuery 3.0は既存のコードを壊すようなことはあまり無いようにしましたが、いくつかの互換性を壊す変更があります。
既存コードの互換性をチェックするのにjQuery Migrate pluginが役に立つでしょう。
今回のリリースには、モダンブラウザのみ(IE9以上)に対応したjQuery 3.0と、IE8も対応しているjQuery Compat 3.0の2つがあります。
CDNからDLするか直接リンクすることで利用できます。
https://code.jquery.com/jquery-3.0.0-alpha1.js
https://code.jquery.com/jquery-compat-3.0.0-alpha1.js
またnpmからも取得できます。
npm install jquery@3.0.0-alpha1
npm install jquery-compat@3.0.0-alpha1
主な変更点
.hide()
と.show()
の仕組みが変更
ご存じの通り、.hide()
メソッドはCSSにdisplay: none
をセットし、.show()
メソッドはdisplay
をクリアすることで、HTML要素を表示/非表示にしていました。
一見とてもシンプルに見えますが、実はとても複雑な特殊分岐をしていました。
display
が次にどうなるかを決めるのにとても多くの処理が必要で、場合によっては単純な推測に過ぎず、間違っている場合すらありました。
またこれらのメソッドはHTML要素にstyle
アトリビュートを追加するので、レスポンシブデザインのようなmediaクエリを用いた要素の表示/非表示と相性が悪いものでした。
jQueryはorientationchange
やresize
イベントを監視してマニュアルで表示/非表示を切り替えており、mediaクエリが目指すエレガントな方法を壊すものでした。
上に述べたのは気が狂いそうな複雑さ全体の半分程度に過ぎません。この特殊処理は複雑で不完全なだけでなく、パフォーマンスに重大な悪影響がありました。
今回は実験的に、原点に立ち返ってこれらのメソッドをシンプルにしました。この変更は既存コードを壊す場合があります。
jQuery 3.0ではdisplay: none
がセットされた要素に.show()
を行ってもdisplay
を上書くことはしません。
jQuery 3.0に移行する際の一番大事なルールは、
CSSでdisplay: none
をセットし、その要素を.show()
や.fadeIn()
などで表示させようとしない
です。
はじめから要素を非表示にしたい場合、"hidden"のような名前のクラスを付与し、このクラスにdisplay: none
のCSSを定義するのがベストな方法です。表示/非表示を切り替える場合、.addClass("hidden")
や.removeClass("hidden")
をするといいでしょう。
もしくは要素がページ上に表示されるより前に、.ready()
のなかで.hide()
することができます。
また.css("display", "block")
などでstyleを上書きすることができます。
今回のリリースの中でこの変更が一番難しく議論の余地があるものなので、alphaで早めに出して様子を見たいと思っています。
https://github.com/jquery/jquery/issues/1767
https://github.com/jquery/jquery/issues/2057
https://github.com/jquery/jquery/issues/2308
補足)
jQueryは要素の表示/非表示を、show/hide関数で一括で扱うことを諦めた(もしくはやるべきではないという考えに至った)という印象を受けました。
上記のように"hidden"クラスを作り、それをtoggleするのがベストな方法であると考えます。
.data()
のキーの特殊ケース
HTML5のdataset仕様書により近づけるように修正しました。
すべてのdataキーは取得時でも常に、kebab-case(ハイフンつなぎ)からcamelCaseに変換されます。
また数字はこの変換には当てはまらなくなります。
"foo-bar"と"fooBar"は同等に扱われますが、"foo-42"と"foo42"は差別化されるようになります。
jQuery.DeferredのPromises/A+との互換性向上
jQuery.DeferredオブジェクトはPromises/A+やECMAScript2015のPromiseとの互換性向上の更新がなされ、Promises/A+仕様テストスイートをパスしました。
.catch()
メソッドの追加や.then()
メソッドの大幅な変更が行われました。
-
.then()
の中で投げられた例外オブジェクトはrejectの値となります(onRejectedに渡されます)。今までは例外が投げられると関数呼び出しの上流に伝播し、コールバックの実行を中止して親子両方のDeferredオブジェクトが回復不能な状態にロックされました。 -
.then()
によって生成されたDeferredオブジェクトの状態を、コールバック関数から操作できるようになります。上記の通り例外オブジェクトがrejectの値となり、コールバックの返り値がthenableになります。 - コールバックが常に非同期に実行されます
-
deferred.progress()
のコールバック内ではresolveすることができなくなります
https://github.com/jquery/jquery/issues/1722
https://github.com/jquery/jquery/issues/2102
補足)
Promise自体が分からなかったり、不明点がある場合はこちらが参考になります。
http://azu.github.io/promises-book/
jQuery.ajaxの特殊なDeferredメソッド廃止
jqXHRオブジェクトはPromiseですが、途中で停止させる.abort()
のような追加メソッドも持っています。
AJAXのような非同期処理にPromiseパターンを使うことにユーザーは慣れてきたので、jQuery.ajaxが返すPromiseに特殊な場合を持たせるのは不適切になってきました。
具体的には.success()
, .error()
, .complete()
がなくなります(.done()
, .fail()
, .always()
は使えます)。
同名のコールバックはそのまま存在し、非推奨にもなりませんので注意してください。Promiseのメソッドだけの変更です。
$.ajax({
...
success: callback, // これはOK
...
});
エラーを黙って無視しないように
今までjQueryは、エラーを投げるよりもなにかしらの値を返すようにする場合がありました。例えばwindowのoffsetを取得しようとすると{ top: 0, left: 0 }
を返していました。
jQUery 3.0 alphaでは実験的に、このような変なリクエストは無視せず、エラーを投げるようにしました。
.width()
と.height()
が整数ではなく小数を返すように変更
今までjQueryはwidthとheightの値を整数に丸めていました。
IEやFirefoxのようなサブピクセルの値(小数値px)を返すブラウザにおいて、正確な値が必要になる場合があります。
ブラウザが小数値を返す限り、jQueryはそのままその小数値を返すようになりました。
非推奨のイベントエイリアスの廃止
jQuery 1.8から非推奨だった.load
, .unload
, .error
が廃止しました。
.on()
を使いイベントリスナーを登録するようにしてください。
jQuery.swap, jQuery.buildFragment, jQuery.domManipの隠蔽
これらのメソッドはjQueryが内部的にのみ利用することを想定されておりドキュメントにも記載されたことはありません。混乱しないよう、これらをprivateなものにしました。
https://github.com/jquery/jquery/issues/2224
https://github.com/jquery/jquery/issues/2225
requestAnimationFrame
の復活
requestAnimationFrame
APIを使えるIE8, IE9以外の多くのプラットフォームにおいて、jQueryのアニメーションもこのAPIを利用するようになりました。アニメーションがスムーズになりCPU負荷が減り、モバイル端末のバッテリー節約になります。
jQueryは数年前requestAnimationFrame
を利用しようと試みましたが、既存コードとの深刻な互換性の問題があり取り下げました。
ブラウザのタブが裏に回った時にアニメーションを停止させることにより、これらの問題はほとんどが解決されたと考えています。
.unwrap()
メソッドが引数をとれるように
今までは.unwrap()
メソッドは引数も取ることができず、親を取り除くようにしていましたが、引数を取れるようになり、取り除く親要素を指定できるようになりました。
いくつかのjQueryカスタムセレクタのパフォーマンス向上
GoogleのPaul Irish氏のお陰で、:visible
や:hidden
のようなカスタムセレクタの特殊処理を省略でき、大幅な性能向上となりました(最大で17倍)。
この性能向上があったとしても:visible
や:hidden
のようなセレクタはコストが高いことを意識しておいてください。なぜなら要素が実際に表示されているかの決定はブラウザに依存しており、最悪の場合、CSSやpageレイアウト全体を再帰処理することになります。
ほとんどの場合で、これらセレクタの使用を控えろというほどではありませんが、実際に自分のページでテストしてパフォーマンスに影響があるか調べて決めるといいでしょう。