jQuery対document.querySelectorAll


161

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

それで問題はこれです:jQueryの最も強力な資産が純粋なJavaScriptで達成できるのに、なぜjQueryのオーバーヘッドに「リスク」があるのでしょうか?

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

何かご意見は?


4
(1)jQueryを使用すると、DOMトラバーサル/変更がはるかに迅速かつ簡単になります。(2)querySelectorメソッドで機能しない独自のセレクターを追加します。(3)jQueryを使用すると、AJAX呼び出しがはるかに迅速かつ簡単になります。(4)IE6 +でのサポート。きっともっとたくさんのポイントが出てくると思います。
James Allardice、2012

12
(5)...怠惰なタイピストの省略表現$()は必須です。
デクスターHuinda

4
はい、なぜもっと速いのですか?jQueryは、私が知る限り、通常のJavaScriptに変換されます...
Joel_Blum

4
@JamesAllardice-クロスブラウザXMLHttpRequestの「すべての混乱」は、たった30行のコードで、一度記述して独自のライブラリに配置します。
RobG

6
@RobG-ええ、私がjQueryを使用しようとしているのがそれだけであると言っているのではありません。これはメリットの1つにすぎません。簡単なDOMトラバーサル(AJAXとquerySelectorAll)が必要で、すべてを古いブラウザーで機能させる必要がある場合は、jQueryが最適です。このように使うべきだと言っているのではありません。
James Allardice、2007

回答:


127

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

ただし、私はこれらのものをjQueryの最強の機能とは見なしませんが、クロスブラウザー互換の方法またはajaxインターフェースでのdom(イベント、スタイリング、アニメーション、および操作)の「動作」のような他のもの。

あなただけのjQueryのセレクタエンジンをしたい場合は、いずれかを使用することができますjQueryの自体が使用している:シズルを道ということ、あなたは厄介なオーバーヘッドなしjQuerysセレクタエンジンのパワーを持っています。

編集:参考までに、私は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倍のコード行になります。また、ネイティブコードの重大な速度の利点(信頼性以外)を損なうブラウザー間の問題を考慮する必要があります。


33
querySelectorAllブラウザ間でどのような不一致がありますか?そして、jQuery querySelectorAll利用可能なときに使用するので、jQueryを使用してこれをどのように解決しますか?

3
確かに、コードの1行には、デバッグ中に非常に煩わしいエンドレスコードのチェーンが含まれる場合があります。
デクスターHuinda 2012

1
"2)いくつかの(おそらくネストされた、または再帰的な)ループを介して子ノードの配列を反復処理し、クラスをチェックします" <<これは全体のがらくたです。前の手順の要素でquerySelectorAllを使用できます。
バヌアン2013

5
@Vanuanこれ必要ないかもしれませんが、私の答えを完全に読んだとしたら、気づいたでしょう。とはいえ、ごちゃごちゃした理由で賛成または反対の投票をすることは自由ですが、失礼な言葉を使用する理由ではないと思います。
クリストフ

2
@Christophこれは簡単なので、IE8以降の互換性を追加しました。それでも速度が非常に優れています(5〜20倍)。IE8のような古いブラウザーでコードの実行が遅くなるというのは、間違った仮定です。
パスカリウス14

60

IE8以降でページを最適化する場合は、jqueryが必要かどうかを本当に検討する必要があります。最新のブラウザーには、jqueryが提供する多くの資産がネイティブに備わっています。

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

div-tagcloudをjqueryからネイティブのjavascript(IE8 +互換)。その結果は印象的です。わずかなオーバーヘッドで4倍速くなります。

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

Jqueryが必要とするかもしれないJqueryは、非常に優れた概要を提供します。どのネイティブバージョンがどのブラウザバージョンに置き換わりますか。

http://youmightnotneedjquery.com/


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


素敵な概要は、コード例のいくつかが間違っているのに... Egが$(el).find(selector)等しくないel.querySelectorAll(selector)と、ネイティブメソッドのパフォーマンスは、しばしば非常に恐ろしいです:stackoverflow.com/q/14647470/1047823
クリストフ・

@Christoph詳細について教えてください、なぜメソッドが異なると思いますか?もちろん、jqueryの方がパフォーマンスが優れているエッジケースがありますが、DOM-Manipulationについては見たことがありません。
パスカリウス2014

1
さらに詳しく説明する必要はありません。私の答えを読んで、フィドルとリンクした記事を見てください。また、(少なくともatm)ネイティブArrayメソッドのほとんどは、ナイーブjs実装と比較して速度が劣ります(最初のコメントの質問にリンクしたように)。そして、これらはエッジケースではなく、むしろ標準ケースです。しかし、再び、この質問の主な焦点は速度ではありませんでした。
クリストフ

2
@Christophもちろん、これらのメソッドは100%等しいわけではなく、jqueryは多くの場合より便利です。これは単なるエッジケースであることを示すために回答を更新しました。実際には、jqueryのパフォーマンスが優れている他のケースは見つかりませんでした。質問の主な焦点はありません。
パスカリウス

+1正解です。もちろん、jQueryのは、いくつかのもののための素晴らしい場所であればどこでも可能な限り..私はゆっくりと、過去4または5年間で生のJavaScriptで古いjQueryのコードを交換してきたと私はそれを使用したもの、私は固体利益を得ると感じたときのこと。
はいバリー

13

jQueryが非常に人気がある理由を理解するには、どこから来たのかを理解することが重要です。

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

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

10年以上が経過した今、jQueryを非常に人気にした多くの機能がjavaScript標準に含まれています。

これらは、2005年には一般に利用できませんでした。現在、これらが今日であるという事実は、なぜjQueryを使用する必要があるのか​​という疑問を明らかにします。実際、jQueryを使用するべきかどうかという疑問がますます高まっています

したがって、jQueryなしで十分にJavaScriptを理解していると思われる場合は、ぜひ実行してください!多くの人がjQueryを使用しているからといって、jQueryを使用することを強いられないでください。


7

それはjQueryが以外にもできるからですquerySelectorAll

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

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

また、ブラウザ間で問題なく、jQueryが提供できるすべての機能(プラグインとAPI)を提供します。

はい、単純なクラスおよびIDセレクターに依存できると思う場合、jQueryは多すぎるため、誇張した見返りを支払うことになります。しかし、そうでなく、すべてのjQueryの良さを活用したい場合は、それを使用してください。


7

jQueryのSizzleセレクタエンジンは、利用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;
    }

そのガードが失敗した場合に使用するのは、で拡張されていないSizzleのバージョンですquerySelectorAll。さらに下には、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)ます。


6

コードの保守性に関しては、広く使用されているライブラリを使用する理由がいくつかあります。

主なものの1つは、それらが十分に文書化されており、ライブラリーに関するヘルプが見つかる...言う... stackexchangeなどのコミュニティーがあることです。カスタムのコード化されたライブラリを使用すると、コーダーがコードの記述よりも多くの時間を費やしてコードを作成するよりも、ソースコードと、場合によってはハウツードキュメントを入手できます。

以下のために独自のライブラリのかもしれない作品を書くあなたが、次の机に座っインターンは、jQueryのようなもので速度まで取得簡単に時間を持つことができます。

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

要約すると、jQueryの主な利点は、簡潔なコードであり、ユビキタスであると考えています。


6

同じ属性を適用する場合の比較を次に示します。たとえば、クラス「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()は最初に一致した要素のみを選択するため、途中までしか使用できません。


4
ここで.forEachを実行します。
Phillip Senn、2016年

さてあなたはいつもより簡単なルートで行くことができますdocument.querySelectorAll('.my-class').forEach(el => el.style.display = 'none');。それでも、たとえ短くても、ネイティブのパフォーマンスは常に優れています。
Alain Cruz、

ユーザーの観点から見ると、0.1秒未満で発生するすべてのことがすぐに発生します。したがって、ネイティブはさらに高速であり、jQueryの実装が0.1秒よりも遅い場合にのみ優れています。そして、実際のアプリケーションでは、それは決して当てはまりません。
ゆりん

3

公式サイトが言うように:「jQuery:書き込みを減らし、より多くを行う、JavaScriptライブラリ」

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

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

1
私はそれに同意しますが、読みやすさはどうですか?関係のない多くのことが起こっている長いコード行をどのように文書化できますか?どのようにしてそのような怪物をデバッグできますか?
Joel_Blum

@ user1032663それはドキュメンテーション規約の問題です。
クリストフ

1
jQuery(または選択した「人気のある」ライブラリ)の代わりに、すべてを最初から作成するのではなく、目的に合った適切に作成されたライブラリを使用します。自分でパーツを作成したか、MyLibraryのようなモジュール式ライブラリを選択して、必要なものだけを含めることができます。
RobG、

2
選択した例は、あなたの主張を実際に証明するものではありません。質問は、「セレクター」州の違いを検索することです。本当に数えないaddClass()show()ください。そしてに関しては$('p.neat')、querySelector / Allを見ることができます。
kumarharsh 2013

document.querySelectorAll('p.neat').forEach(p=>p.classList.add('ohmy'));あとはCSSに任せてください。少し長いコードですが、はるかに効率的です。もちろん、彼のソリューションはレガシーIEの時代にはそれほど利用できませんでした。「Do More」の部分は皮肉なことです。jQueryは何かを見つけるのに約100行のコードを必要とするため、それ以上を行うことは必ずしも生産的ではありません。
Manngo

2

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

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

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

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


1

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

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

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

例えば:

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

以下よりもはるかに優れています:

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

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

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

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

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

バニラJavaScriptでこれを行うには、次のようなものが必要になります。

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

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

jQueryセレクターも少し異なりますが、最新のブラウザー(IE8を除く)はあまりメリットがありません。

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

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

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

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


1
あなたの構文は、「JavaScriptで新しい機能を公開するのが遅い」のような他の間違ったものは言うまでもなく正しくありません。JQueryの仕事は、新しい機能を公開することすらありません。 JavaScriptの10行のように。コメント全体が意味をなさず、多くの間違ったものが含まれています。それを改善することを検討してください。
少年プロ

@Boyproコメントをありがとうございますが、それもエラーでいっぱいです。たぶん、あなたがそんなに気分を害する私の答えについて何を共有したいのでしょう。「正しくない」とは何ですか。さらに良いことに、あなたは自分のanwserを提供したいと思うかもしれません。問題は、バニラJavaScriptがそんなにできるときにjQueryを使用するコストについてです。答えてみてください。
Manngo

0
$( "#id")対document.querySelectorAll( "#id")

取り引きは、配列を作成してそれを分割する$()関数ですが、document.querySelectorAll()を使用すると、配列が作成され、分割する必要があります。


0

マテリアルデザインライトを使用しているときに、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();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.