ほとんどの主要なブラウザーは、 DOMに従って、ページを処理し、ページ内の要素に基づいてドキュメント階層またはドキュメント ツリーを作成します。CSS を適用する場合、通常はドキュメント ツリーを繰り返し処理し、要素ごとに作業を行い、各要素のスタイルシート内の候補セレクターに対して右から左へのマッチングを実行し、 CSSOMに従ってこれらの一致に基づいて CSS ルールを適用します。これは、body > h1.span
たとえばセレクタの場合、ブラウザは最初に各要素をチェックh1
して のクラスを持つ であるspan
かどうかを確認し、次に の直接の子孫であるかどうかをチェックしますbody
。
実装によっては、一致しない可能性が高いケースをフィルタリングするための最適化が行われる場合があります。たとえば、名前空間、タグ名、ID、またはクラス名を確認してから、他の一致するルーチンを試行します。これは、要素を区別する最も一般的な方法です。
この要素ごとの一致パターンにより、ブラウザーは DOM の変更に対してセレクターを効果的に「サブスクライブ」できます。これは、ブラウザーが行う必要があるのは (私が想像するに) DOM の変更を確認し、ルールを適用して要素をリフローすることだけであるためです。それに応じて変更されました。
ただし、それは単純化しすぎています。また、主にスタイルシートでのセレクターのマッチングも指します。仕様では実装が定義されていないため、すべてのセレクターの実装について説明しているわけではありません。
たとえば、DOM のクエリにCSS セレクターを使用しているにもかかわらず、ブラウザーはセレクター API ( document.querySelector()
et al) を異なる方法で実装します。特に、サブスクリプション モデルはまったくありません。Selectors API メソッドによって返されるノード リストは動的に更新されません。§6.2 Finding Elementsから:
メソッドによって返されるNodeList
オブジェクトは、ライブquerySelectorAll()
ではなく、静的でなければなりません([DOM-LEVEL-3-CORE]、セクション 1.1.1)。基礎となるドキュメントの構造に対するその後の変更は、オブジェクトに反映されてはなりません。これは、リストが作成された時点でドキュメント内にあった一致するノードのリストがオブジェクトに代わりに含まれることを意味します。NodeList
Element
このサイトのいくつかの回答によると、jQueryはセレクターの右から左へのマッチングも実行するようですが、サポートするソースは見つかりませんでした。またbody
、ID セレクターが最初に読み取られるなど、多くの最適化も行われています。セレクター API と同様に、jQuery は、セレクター エンジンが呼び出された時点で一致したノードの静的リストを返します。DOM の変更をサブスクライブしてそれに応じてノード リストを更新することはありません (DOM の変更をサブスクライブし、イベント ハンドラーをデリゲートする必要がある場合.on()
は、セレクターで または類似のメソッドを使用する必要があります)。
jQuery が採用する主要な最適化の 1 つは、最初にセレクターを一致させるためにセレクター API に従うことです。これは、JavaScript ではなくブラウザのネイティブ実装を使用することを意味します。セレクターが有効な CSS でサポートされている場合document.querySelectorAll()
、ノード リストを返します。それ以外の場合にエラーが発生した場合、jQuery は独自のセレクター エンジンであるSizzleにフォールバックして DOM をクエリします。
繰り返しますが、ブラウザーの CSS セレクターの実装と厳密には同じではありません。特に、jQuery セレクターと CSS セレクターは、一方が他方を適応させたものであるにもかかわらず、同じものではないためです。