おすすめのjQuery代替ライブラリ

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 8
  • VIEW 3,497

Lhankor_Mhy

score 10868

jQueryがオワコン扱いされるようになって久しいですが、書くのが楽、というメリットは捨てがたいと思います。
というわけで、以下のようなことができる代替ライブラリがありましたらご紹介ください。

DOM処理を書くのがダルイ。
Array.prototype.forEach.call(document.querySelectorAll('div'), function(elem) { elem.styles.color = 'red'; });
この程度ならいいですが、イベントリスナとかつけて回るようなコードだと可読性がjQueryと比べてかなり劣る印象。
その他、:hasセレクタとか、フォームの操作とかも、Vanillaで書くのダルイです。

Ajaxを書くのがダルイ。
var xhr = new XMLHttpRequest();
xhr.open("GET", "/bar/foo.txt", true);
xhr.onload = function (e) {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      console.log(xhr.responseText);
    } else {
      console.error(xhr.statusText);
    }
  }
};
xhr.onerror = function (e) {
  console.error(xhr.statusText);
};
xhr.send(null);
特にjsonpとかめんどくさいです……


Deferred使いたい。
まあ、これは Promise の Polyfill でいいと言えばいいんですが……
エフェクト系ライブラリがPromiseに対応してるわけじゃないのでなんか面倒です。



以上、よろしくお願いします。



追記
オールインワンのライブラリじゃなくてもかまいませんよ。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+5

jQueryがかつてほどの勢いを失っているのには、大きく分けて3つの理由があると考えています。

  • ブラウザの互換性向上
今でこそ標準規格で書いても素直に動くようになってきましたが、昔のIEは特に癖が強く、ライブラリで補わないと同じことを実現できない、というような環境でした。そのIEすらWindows 10ではEdgeが導入され主流の座を追われていくことになるので、基本的なDOM操作についてjQueryを挟んで互換性を図る必要は少なくなっています。

  • ブラウザの機能向上
一昔前は、ブラウザ内でアニメーションさせようとすればJavaScriptで値を変えるしかありませんでしたが、今はCSSレベルでアニメーションできるようになっています。また、汎用で使えるセレクタのquerySelectorAllや、jQueryのaddClasshasClassがそのままDOMに移植されたかのようなclassListなど、ブラウザのDOM機能自体も拡張されています。

  • フロントエンドフレームワークの隆盛
JavaScriptの性能向上・機能強化が行われてきたことで、ちまちま既存のDOMを更新するというのではなく、どかっとJavaScriptからDOM全体を更新する、という実装も現実的となってきました。そうなれば、jQueryの出る幕ではありません。

とはいえ、「フロントエンドフレームワークを使わない」という条件下では、「DOMで直書きする」「機能ごとにライブラリを拾ってくる」「jQueryを使う」という3択になる感じで、jQueryを代替できるようなオールインワンのライブラリはなさそうです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/27 10:16

    ありがとうございます!

    キャンセル

checkベストアンサー

+3

ライブラリではありませんが、全て自前で便利関数を定義するのはどうでしょうか。
取り上げられた事例は決して難しいものではないので不可能ではないと思います。


Array.prototype.forEach.call(document.querySelectorAll('div'), function(elem) { elem.styles.color = 'red'; });

Array.prototype.forEach や document.querySelectorAll をローカル変数にキャッシュすれば短く書けます。

var forEach = (function (_forEach, slice) {
  return function forEach (thisArg) {
    return _forEach.apply(thisArg, slice.call(arguments, 1));
  };
}(Array.prototype.forEach, Array.prototype.slice));

var queryAll = (function (querySelectorAll, doc) {
  return function queryAll (selectorText /*, contextObject */) {
    return arguments.length < 2 ? doc.querySelectorAll(selectorText) : querySelectorAll.call(arguments[1], selectorText);
  };
}(document.querySelectorAll, document));

var query = (function (querySelector, doc) {
  return function query (selectorText /*, contextObject */) {
    return arguments.length < 2 ? doc.querySelector(selectorText) : querySelector.call(arguments[1], selectorText);
  };
}(document.querySelector, document));

console.log(query('p'));
forEach(queryAll('div'), function (element) {
  console.log(element);
});

「いやいや、メソッドチェーンでやりたいんだ」というのであれば、jQuery のようにコンストラクタ内にラップします。
(ただし、このラップ処理はそれなりのコストを支払うのでパフォーマンス低下を惜しむのであれば避けるべきです)

var QueryAll = (function (querySelectorAll, doc) {
  function QueryAll (selectorText /*, contextObject */) {
    var elements;

    if (!(this instanceof QueryAll)) {
      throw new TypeError('Constructor QueryAll requires \x27new\x27');
    }

    elements = arguments.length < 2 ? doc.querySelectorAll(selectorText) : querySelectorAll.call(arguments[1], selectorText);

    for (var i = 0, l = elements.length; i < l; ++i) {
      this[i] = elements[i];
    }

    this.length = l;
  }

  return QueryAll;
}(document.querySelectorAll, document));

Object.defineProperty(QueryAll.prototype, 'forEach', {
  writable: true,
  enumerable: false,
  configurable: true,
  value: Array.prototype.forEach
});

new QueryAll('p').forEach(function (element) {
  console.log(element);
});
QueryAll('p'); // TypeError: Constructor QueryAll requires 'new'

この程度ならいいですが、イベントリスナとかつけて回るようなコードだと可読性がjQueryと比べてかなり劣る印象。

おそらく、複数の要素に同じイベントハンドラを定義する場合と想定しているのだと思いますが、上位ノードで定義してイベントバブリングを利用すれば複数の要素に定義して回り必要はほぼなくなります。
それでも必要な状況があれば、先のコードと同じく、ラップしてください。

Ajaxを書くのがダルイ。

やることがほぼ決まっているのであれば、便利関数 xhr を定義するとか。

Deferred使いたい。
まあ、これは Promise の Polyfill でいいと言えばいいんですが……
エフェクト系ライブラリがPromiseに対応してるわけじゃないのでなんか面倒です。

jQuery ライブラリを jQuery 以外で使おうとすれば無理が生じるので、他作ライブラリ前提なら jQuery 以外の単機能ライブラリを探すのが良いと思います。

怠惰はプログラマの美徳

この格言は「楽をする為の努力を惜しまずしなさい」の意であって「出来るだけ自分の労力を惜しんで楽をしなさい」の意ではないと思います。
小飼弾さんが紹介されている "Programming Perl" では「怠慢(Laziness)」を「全体の労力を減らすために手間を惜しまない気質」と説明されていますね。
楽をする為の仕組み、コードを発明することにプログラマの美徳が存在するのではないでしょうか。

小飼弾 404 Title Not Found - #1 プログラマーの三大美徳その1「怠慢」ITpro

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/27 17:32

    なるほど、大変参考になりました。

    > 楽をする為の仕組み、コードを発明することにプログラマの美徳が存在するのではないでしょうか。

    おっしゃる通りです。



    コードを拝見していてひとつ疑問があったのですが、
    ` return function forEach (thisArg) {`
    この部分を匿名にしていないのにはなにか理由があるのでしょうか。

    キャンセル

  • 2015/10/27 17:52 編集

    > ` return function forEach (thisArg) {`
    > この部分を匿名にしていないのにはなにか理由があるのでしょうか。
    「匿名にしていない」とは「無名関数式」ではなく、「名前付き関数式」を使っている事を指しているのでしょうか。
    関数名は Function#name や Function#toString で参照可能な情報ですから、即時関数のような後で参照しない関数を除いて出来る限り付けるべきだと思います。
    ネイティブ関数でも Array.prototype.forEach.name === 'forEach' のように関数名が割り当てられています。

    キャンセル

  • 2015/10/27 19:27

    ありがとうございます、勉強になりました。
    改めて`Function.name`を確認してみましたが、ES6からの標準でIE未対応なんですね、びっくりです。(というか、日本語版のMDNではまだ非標準仕様になってる)

    キャンセル

0

DOM操作の時代は終わった!
これからはReactですよ、奥さん。

AngulerJSのほうがいいって?
駄目だ、奴にはjQLiteなるjQueryの亡霊がついて回るぞ。
いつまでもjQueryからは逃れられないのだ!!!

といいながらajaxはjQueryを使い続けているんですけどね。だって便利なんだもん。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/27 20:10

    なにを言ってるんですか、時代は Web Components ですよ!
    それまでは Polymer を使いながら Google お得意の仕様変更に恐れおののくのが正しい Javascript 使いの姿ってもんです。



    ご意見ありがとうございましたw

    キャンセル

0

Angular.js(1.*系)

Promiseの拡張実装であるQを内蔵しています。
- xhrのラッパ$httpを内蔵しており、ajaxをPromiseで発行できます。デフォルトでjsonを待ち、パース済みのオブジェクトを受け取れます。
- DOM操作を抽象的に行えます。<div hoge>と書かれたタグをdirective('hoge',function(scope,element,attrs){})という風に処理できます。
- jQueryの簡易実装であるjQLiteを内蔵しています。
- windowに依存した実装のライブラリが殆どなのでNodejs上で動作しませんphantomjsを使用して間接的にServerSideRenderingを行うか、jsdomを利用する方法があります。

React.js(0.14系)

Promiseを内蔵していません。
xhrのラッパを内蔵していません。superagentaxiosを使うのがオススメです。
- DOM操作を抽象的に行うことに特化しています。また、htmlを直接操作することには向いていません。これはReactの基本コンセプトに基づくものです
Nodejs上で動作しますNodejsのExpress4と併用することでServerSideRenderingが可能です。これについて日本語の記事は存在しませんので、細部を自力で実装する必要があります。

VueMagJSMithrilRiotについては、コードを書いたことがないので割愛します。
各フレームワークについて、何があって何が無いのか。何が出来て何が出来ないのか。ご存じの方居ましたら、情報を頂けると嬉しいです。
文中の間違いも指摘して頂けると嬉しいです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/31 20:22

    ありがとうございます。

    それらのものは、jQueryとは目的が違うように感じています。

    キャンセル

-1

jQuery 使えばいいと思うし、処理を書くのがだるいって、
そもそも同じ(似たような)処理をまとめるのがプログラマの役目じゃないかな?

代替を示したところで、代替がたたかれれば、それになびかれるんじゃないの?
結局同じことだ
だるいならやめちまえって思う。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/27 10:32

    「jQuery 使えばいい」というご意見ありがとう。俺もわりと同意だね。

    ところで、怠惰はプログラマの美徳らしいよ? ダルイことを改善するのは大事だと思うし、それを改善する他人が書いた素晴らしいコードがあるなら利用しない手はないと思うけど、どうだろう。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる