web-dev-qa-db-ja.com

jQuery vs document.querySelectorAll

JQueryの最も強力な資産は、DOM内の要素をクエリおよび操作する方法であると何度か聞きました。CSSクエリを使用して、通常のjavascriptでは非常に難しい複雑なクエリを作成できます。ただし、私が知る限り、Internet Explorer 8以降でサポートされているdocument.querySelectorまたはdocument.querySelectorAllでも同じ結果を得ることができます。

質問は次のとおりです。純粋なJavaScriptで最も強力な資産を達成できる場合、なぜjQueryのオーバーヘッドを「リスク」にするのでしょうか。

JQueryには、クロスブラウザーAJAX、Niceイベントアタッチなど、CSSセレクター以上のものがあることを知っています。しかし、そのクエリ部分はjQueryの強さの非常に大きな部分です。

何かご意見は?

147
Joel_Blum

document.querySelectorAll() ブラウザ間でいくつかの不整合があり、古いブラウザではサポートされていませんこれはおそらく今ではもう問題を引き起こさないでしょう。非常に直感的ではない スコーピングメカニズム およびその他の それほど素敵ではない機能 があります。また、javascriptを使用すると、これらのクエリの結果セットを操作するのが難しくなります。これは多くの場合、実行したいことです。 jQueryは、filter()find()children()parent()map()not()などの機能を提供します。擬似クラスセレクターで動作するjQueryの機能は言うまでもありません。

ただし、jQueryの最も強力な機能ではなく、crossbrowser compatiblewayまたはajaxインターフェイス。

JQueryのセレクターエンジンだけが必要な場合は、jQuery自体が使用している1つを使用できます:Sizzle厄介なオーバーヘッドのないjQueryセレクターエンジンのパワー。

編集:記録のためだけに、私はバニラJavaScriptの大ファンです。それにもかかわらず、1行のjQueryを記述する10行のJavaScriptが必要になる場合があるという事実です。

もちろん、次のようにjQueryを記述しないように訓練する必要があります。

$('ul.first').find('.foo').css('background-color', 'red').end().find('.bar').css('background-color', 'green').end();

これは非常に読みにくいですが、後者は非常に明確です:

$('ul.first')
   .find('.foo')
      .css('background-color', 'red')
.end()
   .find('.bar')
      .css('background-color', 'green')
.end();

同等のJavaScriptは、上記の擬似コードで示されるように、はるかに複雑になります。

1)要素を見つけ、すべての要素または最初の要素のみを取得することを検討します。

// $('ul.first')
// taking querySelectorAll has to be considered
var e = document.querySelector("ul.first");

2)いくつかの(おそらくネストされた、または再帰的な)ループを介して子ノードの配列を反復処理し、クラスをチェックします(クラスリストはすべてのブラウザーで使用できるわけではありません!)

//.find('.foo')
for (var i = 0;i<e.length;i++){
     // older browser don't have element.classList -> even more complex
     e[i].children.classList.contains('foo');
     // do some more magic stuff here
}

3)CSSスタイルを適用する

// .css('background-color', 'green')
// note different notation
element.style.backgroundColor = "green" // or
element.style["background-color"] = "green"

このコードは、jQueryを使用して記述するコードの少なくとも2倍のコード行になります。また、ネイティブコードの (速度の優位性) (信頼性に加えて)を損なうクロスブラウザーの問題を考慮する必要があります。

115
Christoph

IE8以降向けにページを最適化する場合は、jqueryが必要かどうかを本当に検討する必要があります。最新のブラウザには、jqueryが提供する多くのアセットがネイティブにあります。

パフォーマンスを重視する場合は、ネイティブを使用して、信じられないほどのパフォーマンスの利点を得ることができます(2-10高速) javascript: http://jsperf.com/jquery-vs-native-selector-and-element-style/2

Div-tagcloudをjqueryからnative javascript(IE8 +互換)に変換しました。結果は印象的です。わずかなオーバーヘッドで4倍高速。

                    Number of lines       Execution Time                       
Jquery version :        340                    155ms
Native version :        370                    27ms

Jqueryは必要ないかもしれませんが、どのネイティブバージョンがどのブラウザバージョンに取って代わるかという、本当に素晴らしい概要を提供します。

http://youmightnotneedjquery.com/


付録:ネイティブメソッドがjqueryと競合する速度の比較

58
Pascalius

JQueryの人気の理由を理解するには、私たちがどこから来たのかを理解することが重要です!

約10年前、トップブラウザーはIE6、Netscape 8、Firefox 1.5でした。当時は、 Document.getElementById() 以外に、DOMから要素を選択するクロスブラウザの方法はほとんどありませんでした。

そのため、jQuery が2006年にリリースされたとき 、それはかなり革命的でした。当時、jQueryは柔軟性とブラウザーサポートが前例のないものであったため、HTML要素を簡単に選択/変更し、イベントをトリガーする方法の標準を設定しました。

10年以上経った今、jQueryをこれほど人気にした多くの機能がjavaScript標準に含まれるようになりました。

これらは、2005年には一般的に入手できませんでした。今日、それらが明らかにjQueryを使用する理由の疑問を明らかにしています。そして実際、人々はますますjQueryを使用すべきかどうか疑問に思っています.

したがって、jQueryを使用せずにJavaScriptを十分に理解していると思われる場合は、実行してください。他の多くの人がjQueryを使用しているという理由だけで、jQueryの使用を強制されることはありません。

12
John Slegers

jQueryのシズルセレクターエンジンは、querySelectorAllが使用可能であれば、それを使用できます。また、均一な結果を達成するために、ブラウザー間の不整合を滑らかにします。 jQueryのすべてを使用したくない場合は、Sizzleを個別に使用できます。これは、発明するための非常に基本的なホイールです。

以下は、jQuery(w/Sizzle)が選別する種類を示すソースからのチェリーピッキングです。

Safariの奇癖モード:

if ( document.querySelectorAll ) {
  (function(){
    var oldSizzle = Sizzle,
      div = document.createElement("div"),
      id = "__sizzle__";

    div.innerHTML = "<p class='TEST'></p>";

    // Safari can't handle uppercase or unicode characters when
    // in quirks mode.
    if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
      return;
    }

そのガードが失敗した場合、querySelectorAllで拡張されていないSizzleのバージョンが使用されます。さらに下には、IE、Opera、およびBlackberryブラウザーの不整合に対する特定のハンドルがあります。

  // Check parentNode to catch when Blackberry 4.6 returns
  // nodes that are no longer in the document #6963
  if ( elem && elem.parentNode ) {
    // Handle the case where IE and Opera return items
    // by name instead of ID
    if ( elem.id === match[3] ) {
      return makeArray( [ elem ], extra );
    }

  } else {
    return makeArray( [], extra );
  }

そして、他のすべてが失敗した場合、oldSizzle(query, context, extra, seed)の結果を返します。

7
KGZM

それは、jQueryがquerySelectorAllよりもはるかに多くのことができるからです。

まず、jQuery(特にSizzle)は、CSS2.1-3セレクターをサポートしていないIE7-8などの古いブラウザーで動作します。

さらに、Sizzle(jQueryの背後にあるセレクターエンジン)は、:selected疑似クラス、高度な:not()セレクター、$("> .children")のようなより複雑な構文など、より高度なセレクターインストゥルメントを提供します。

そして、それはjQueryが提供できるすべてのもの(プラグインとAPI)を完全に提供し、クロスブラウザーで実行します。

はい、単純なクラスとIDセレクターに依存できると思うなら、jQueryはあなたにとってはやり過ぎであり、誇大な見返りを払うことになります。しかし、もしそうでなく、すべてのjQueryの長所を利用したい場合は、それを使用してください。

6
MaxArt

同じ属性を適用する場合の比較を次に示します。クラス「my-class」のすべての要素を非表示にします。これがjQueryを使用する理由の1つです。

jQuery:

$('.my-class').hide();

JavaScript:

var cls = document.querySelectorAll('.my-class');
for (var i = 0; i < cls.length; i++) {
    cls[i].style.display = 'none';
}

JQueryはすでに非常に人気があるため、document.querySelector()を$()のように動作させる必要があります。代わりに、document.querySelector()は最初に一致した要素のみを選択するため、半分しか役に立ちません。

5
Steven

コードの保守性の観点から、広く使用されているライブラリに固執する理由がいくつかあります。

主なものの1つは、ドキュメントが充実していること、そして... stack ...などのコミュニティがあり、ライブラリのヘルプが見つかることです。カスタムコード化ライブラリを使用すると、ソースコード、およびハウツードキュメントを作成できます。ただし、コーダーがコードを記述するよりもドキュメントの作成に多くの時間を費やしている場合を除きます。

独自のライブラリを書くことはyoでうまくいくかもしれませんが、次の机に座っているインターンはjQueryのようなものに慣れるのがより簡単な時間を持つかもしれません。

必要に応じて、ネットワーク効果と呼びます。これは、コードがjQueryで優れていると言うことではありません。コードの簡潔な性質により、表示しているファイルに一度に表示されるより機能的なコードがあるためだけに、すべてのスキルレベルのプログラマーの全体的な構造を把握しやすくなります。この意味で、5行のコードは10よりも優れています。

要約すると、jQueryの主な利点は簡潔なコードであり、どこにでもあると考えています。

4
Dom Day

本当の答えは、jQueryはすべての主要なブラウザでquerySelector/querySelectorAllが利用可能になるずっと前に開発されたと思います。

jQueryは2006年 の最初のリリース。実際、jQueryでさえも CSSセレクターを実装した最初のものではありませんでした

IEは最後のブラウザでしたquerySelector/querySelectorAllを実装します。その8番目のバージョン 2009年にリリースされました

そのため、DOM要素セレクターはjQueryの最強点ではなくなりました。ただし、要素のcssやhtmlコンテンツを変更するショートカット、アニメーション、イベントバインディング、ajaxなど、まだまだ多くの利点があります。

2
Vanuan

公式サイトには次のように書かれています:「jQuery:より少なく、もっともっと、JavaScriptライブラリ」

ライブラリなしで次のjQueryコードを翻訳してみてください

$("p.neat").addClass("ohmy").show("slow");
2
simon xu

古い質問ですが、半年後、再検討する価値があります。ここでは、jQueryのセレクターの側面についてのみ説明します。

document.querySelector[All]all IE8までの現在のブラウザーでサポートされているため、互換性は問題になりません。また、パフォーマンスの問題はありませんでした(document.getElementByIdよりも遅いはずでしたが、私自身のテストでは少し速いことを示唆しています)。

したがって、要素を直接操作する場合は、jQueryよりも優先されます。

例えば:

var element=document.querySelector('h1');
element.innerHTML='Hello';

vastlyより優れています:

var $element=$('h1');
$element.html('hello');

何かをするためには、jQueryは100行のコードを実行する必要があります(jQueryが実際に何をしていたかを確認するために上記のようなコードをたどったことがあります)。これは明らかに全員の時間の無駄です。

JQueryのその他の重要なコストは、新しいjQueryオブジェクト内にすべてをラップするという事実です。このオーバーヘッドは、オブジェクトを再度ラップ解除する必要がある場合、またはオブジェクトメソッドの1つを使用して、元の要素で既に公開されているプロパティを処理する必要がある場合は特に無駄です。

ただし、jQueryの利点は、コレクションの処理方法にあります。要件がset複数の要素のプロパティである場合、jQueryには組み込みのeachメソッドがあり、次のようなことができます。

var $elements=$('h2');  //  multiple elements
$elements.html('hello');

Vanilla JavaScriptでこれを行うには、次のようなものが必要です。

var elements=document.querySelectorAll('h2');
elements.forEach(function(e) {
    e.innerHTML='Hello';
});

気が遠くなる人もいます。

jQueryセレクターもわずかに異なりますが、最新のブラウザー(IE8を除く)には大きな利点はありません。

原則として、newプロジェクトにjQueryを使用しないように注意します。

  • jQueryは、プロジェクトのオーバーヘッドとサードパーティへの依存性を増大させる外部ライブラリです。
  • jQuery関数は、非常に高価で、処理の面で優れています。
  • jQueryは、学習する必要があり、コードの他の側面と競合する可能性のある方法論を課しています。
  • jQueryはJavaScriptの新機能の公開に時間がかかります。

上記のいずれも重要でない場合は、あなたがすることをしてください。ただし、jQueryはクロスプラットフォーム開発にとって以前ほど重要ではなくなりました。最新のJavaScriptとCSSは以前よりもはるかに進化しているためです。

これは、jQueryの他の機能については言及していません。しかし、私も彼らはもっとよく見る必要があると思います。

0
Manngo
$( "#id")vs document.querySelectorAll( "#id")

対処法は、配列を作成してからそれを分割する$()関数ですが、document.querySelectorAll()では配列を作成するため、分割する必要があります。

0
user8903269

これについてのコメントですが、マテリアルデザインライトを使用する場合、jqueryセレクターは何らかの理由でマテリアルデザインのプロパティを返しません。

にとって:

<div class="logonfield mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
        <input class="mdl-textfield__input" type="text" id="myinputfield" required>
        <label class="mdl-textfield__label" for="myinputfield">Enter something..</label>
      </div>

これは動作します:

document.querySelector('#myinputfield').parentNode.MaterialTextfield.change();

これはしません:

$('#myinputfield').parentNode.MaterialTextfield.change();
0
Ashvin Bhuttoo