これからは今まで以上に、jQueryが必要なくなるかもしれない
Post on:2017年7月14日
3, 4年前あたりから、jQuery無しでこう記述するとか、jQueryの一部の機能を代替する軽量スクリプトなどが出始めました。
2017年も半年が過ぎ、その状況はさらに変わり始めています。
(Now More Than Ever) You Might Not Need jQuery
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- 現在のブラウザ事情
- jQueryに替わる、JavaScriptの選択肢
- マイクロライブラリの台頭
- IE9への対応はポリフィルで
- NodeListの反復
- jQueryは遅いのか?
- jQueryについて私が嫌いなもの
- $なしでは生きていけない?
現在のブラウザ事情
jQueryが2006年にリリースされてから、DOMとブラウザのAPIは飛躍的に向上しています。2013年に「You Might Not Need jQuery(jQueryを必要としないかもしれない)」が公開されました。
わたしは古い記事を焼き直すことを望むわけではありませんが、最近ではブラウザの事情も大きく変化してきたため、見直す必要があると思います。
ブラウザは、新しいAPIを実装し続けています。
jQueryのメソッドに替わる、新しいVanilla JavaScriptの選択肢を試してみましょう。
※Vanilla JavaScriptとはバニラアイスのようにシンプルで、何もトッピングされていない素のJavaScriptのことです。
jQueryに替わる、JavaScriptの選択肢
ページから要素を削除する
Vanilla DOMを使ってページから要素を削除しなければならなかったことを覚えていますか? 「el.parentNode.removeChild(el);」でしょうか?
jQueryと新しい改良されたVanillaの記述を見てみましょう。
1 2 |
var $elem = $(".someClass") // 要素を指定 $elem.remove(); // 要素を削除 |
1 2 |
var elem = document.querySelector(".someClass"); // 要素を指定 elem.remove() // 要素を削除 |
※「$elem」はjQueryで選択された要素、「elem」はJavaScriptで選択されたネイティブのDOM要素です。
要素の前に追加する
1 |
$elem.prepend($someOtherElem); |
1 |
elem.prepend(someOtherElem); |
他の要素の前に要素を挿入する
1 |
$elem.before($someOtherElem); |
1 |
elem.before(someOtherElem); |
要素を別の要素に置き換える
1 |
$elem.replaceWith($someOtherElem); |
1 |
elem.replaceWith(someOtherElem); |
指定されたセレクタに一致する最も近い祖先を検索する
1 |
$elem.closest("div"); |
1 |
elem.closest("div"); |
DOM操作メソッドのブラウザのサポート状況
このメソッドには、適切なレベルのブラウザサポートが用意されています。
DOM操作メソッドのサポート状況
※Edgeは現在、重要度高で実装検討中となっています。
要素をフェードイン
1 |
$elem.fadeIn(); |
CSSを自分で書くことで、要素をアニメーション化する方法は簡単に利用できます。ここでは単純なフェードを行います。
1 2 3 4 5 |
.thingy { display: none; opacity: 0; transition: .8s; } |
1 2 |
elem.style.display = "block"; requestAnimationFrame(() => elem.style.opacity = 1); |
イベントハンドラのコールバックを1回だけ呼び出す
1 |
$elem.one("click", someFunc); |
以前は、コールバック関数の中でremoveEventListenerを呼び出す必要がありました。
1 2 3 4 5 6 |
function dostuff() { alert("some stuff happened"); this.removeEventListener("click", dostuff); } var button = document.querySelector("button"); button.addEventListener("click", dostuff); |
しかし、最近は非常にクリーンなコードです。
addEventListenerに渡される3番目のオプションのパラメータを見たことがあるかもしれません。イベントキャプチャとイベントバブリングのどちらかを決定するのはブール値です。しかし、今日では第3引数は構成オブジェクトの場合もあります。
1 |
elem.addEventListener('click', someFunc, { once: true, }); |
イベントキャプチャを使用したいだけでなく、コールバックが1回しか呼び出されないようにするには、コンフィギュレーションオブジェクトでも指定できます。
1 2 3 4 |
elem.addEventListener('click', myClickHandler, { once: true, capture: true }); |
アニメーション
jQueryの.animate()メソッドは、記述がかなり制限されています。
1 2 3 4 5 6 7 |
$elem.animate({ width: "70%", opacity: 0.4, marginLeft: "0.6in", fontSize: "3em", borderWidth: "10px" }, 1500); |
すべてのプロパティの値は、数値で指定する必要があります。数値以外の値は、jQueryの機能を使用してアニメーション化することはできません。計算式や文字列が利用できないため、Web Animations APIを使った方が良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var elem = document.querySelector('.animate-me'); elem.animate([ { transform: 'translateY(-1000px) scaleY(2.5) scaleX(.2)', transformOrigin: '50% 0', filter: 'blur(40px)', opacity: 0 }, { transform: 'translateY(0) scaleY(1) scaleX(1)', transformOrigin: '50% 50%', filter: 'blur(0)', opacity: 1 } ], 1000); |
Ajax
jQueryのもう一つの重要なセールスポイントは、Ajaxでした。jQueryではXMLHttpRequestの酷さを抽象化しました。
1 2 3 |
$.ajax('https://some.url', { success: (data) => { /* データを詰め込む */ } }); |
新しいfetch APIは、XMLHttpRequestの上位互換で、最新のブラウザすべてにサポートされています。
1 2 3 4 5 |
fetch('https://some.url') .then(response => response.json()) .then(data => { // do stuff with the data }); |
実際はこのコードよりも少し複雑になる可能性があります。たとえば、fetch()から返されたPromiseはHTTPエラー状態で拒否されません。しかし、XMLHttpRequestの上に構築されたものよりはるかに汎用性があります。
マイクロライブラリの台頭
axiosはAjaxの分野で、人気のあるライブラリです。
これはマイクロライブラリの素晴らしい例で、ライブラリとは1つのことを行うように設計されています。ほとんどのライブラリはjQueryと同等かテストされていませんが、jQueryに替わる魅力的な選択肢です。
IE9への対応はポリフィルで
あなたはDOMが使いやすいということを知っているでしょう。しかし、「IE9をサポートする必要があるので、jQueryを使わなくては」と考えるかもしれません。
そのような時には、Polyfills(ポリフィル)でそのギャップを埋めることができます。新しいブラウザの機能を使用する場合は、ポリフィルを見つけて、ページに使用する必要がありました。IE9で欠けているすべての機能に対してこれを行うのは難しい作業です。
しかし、現在ではそれは簡単です。
1 |
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script> |
このシンプルなスクリプトタグは、あなたが望む何かをポリフィルできます。ポリフィルについては、Polyfill.ioが詳しいです。
NodeListの反復
jQueryの大規模な採用は、ブラウザのバグやIEに対応することによってのみ促進されたわけではありません。今日、jQueryには残りの1つのセールスポイント、NodeListの反復があります。
NodeListの反復は、DOMにとって根本的に重要です。NodeListが反復可能ではないという合理性は否定されています。古典的なforループは、最もパフォーマンスに最適化されたアプローチかもしれませんが、入力を楽しむものではありません。そして、私たちはこの醜さに終わりを告げました。
1 |
var myArrayFromNodeList = [].slice.call(document.querySelectorAll('li')); |
もしくは、
1 |
[].forEach.call(myNodeList, function (item) {...} |
最近ではnodeListを配列に変換するより、エレガントなArray.fromを使用されています。
1 |
Array.from(querySelectorAll('li')).forEach((li) => /* do something with li */); |
さらにシンプルに書くこともできます。
1 |
document.querySelectorAll('li').forEach((li) => /* do some stuff */); |
Edgeは反復可能なnodeListをサポートしていないモダンブラウザですが、現在それに取り組んでいます。
参考: Microsoft Edge Developer
jQueryは遅いのか?
jQueryは、Vanilla JavaScriptよりも速いかもしれませんが、それはJavaScriptをより良く学ぶ良い理由です。Paul IrishはjQueryプロジェクトの貢献者であり、一つの結論を出しました。
jQueryについて私が嫌いなもの
jQueryはブラウザのAPIのひどい部分だけをよくするのではなく、すべてを置き換えようとします。例えば、NodeListではなくjQueryのオブジェクトを返すことで、組み込みのブラウザのメソッドは本質的に制限されています。つまり、すべてがjQueryに縛られるということです。
初心者にとって、何かをする際に2つの重複した方法があることは、今となっては障害です。容易に他の人のコードを理解し、Vanilla JavaScriptとjQueryを必要とするには、2倍の習得時間が必要になります。
$なしでは生きていけない?
jQueryの「$」が好きな人も多いでしょう。マイクロライブラリの一部では、その機能をエミュレートするものもあります。
- Bliss.jsでは$構文を使用しますが、NodeListを返します。
- Bling.jsではjQueryを使わずに、$構文を利用できます。
- min.jsでは$構文をはじめ、多くのイベントを利用できます。
わたしは反jQueryというわけではありません。多くの制作者がjQueryを選択していることも知っています。使い慣れたAPIを使用するのであれば、それを捨てる大きな理由はありません。また、制作者の募集要項の必要スキルとして、挙げられているのも事実です。
しかし、誰かがスタートすることに対しては、悪い選択肢だと思います。IE11はその恩恵を受ける最後の砦です。IEが消えると、ブラウザ全体が豊かになり、jQueryはDOMの汚れた過去からの遺物と見なされるようになるでしょう。
sponsors