これはセレクターに固有のものではありません:not(...)
。:has(...)
実際、Sizzleのすべての疑似は引用符で囲まれた引数を許可します。疑似引数のパターンは次のように定義されます。
pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)"
の時点での行で見つけることができます91
sizzle.js
831c9c48...
少し読みやすくするために、それにインデントを追加しましょう。残念ながら、これはまだ正規表現であるため、「もう少し読みやすい」ということには、まだ多くの要望があります。
pseudos = (
":(" + characterEncoding + ")" +
"(?:" +
"\\(" + // literal open-paren
"(?:" +
"(['\"])" + // literal open-quote
"((?:\\\\.|[^\\\\])*?)" + // handle backslash escaping
"\\2" + // close-quote
"|" + // - OR -
"(" +
"[^()[\\]]*" +
"|" +
"(?:" +
"(?:" + attributes + ")" +
"|" +
"[^:]" +
"|" +
"\\\\." +
")*" +
"|" +
".*" +
")" +
")" +
"\\)" + // literal close-paren
"|" + // ie, 'or nothing'
")"
);
これからの主なポイントは次のとおりです。疑似属性の引数の前後に一重引用符または二重引用符を使用できます。バックスラッシュのエスケープは適切に処理されるため、任意の文字列を引数として渡すことができます。「文字列」の部分は、上記の正規表現の「セレクター」の部分と同じ一致インデックスになります。つまり、要するに、それがそれらが同等に扱われる理由ですpseudos
。パターンが2つを区別しないためです。編集: jQuery 1.8.2以降、引用符のある引数とない引数は、より明示的に同等です。jQuery gitリポジトリでこのコードを見つけることができないようです[ヘルプをいただければ幸いです]が、a0f48b6ad5322b35383ffcb6e2fa779b8a5fcffcのsha1sumを持つgoogleによってホストされているバージョン1.8.2にはオンラインで機能
"PSEUDO":
があります4206
、「引用符で囲まれた」引数と「引用符で囲まれていない」引数の違いを明示的に検出し、両方が同じ場所に配置されるようにします。このロジックは、引数の対象となる疑似のタイプ(「位置」かどうか)を区別しません。
SizzleはJavascript文字列を使用して選択プロセスを開始するため、引数が関数に渡されるときに「文字列」と「セレクター」の区別はありません。そのような区別をすることは可能ですが、私が知る限り、実際に何が望まれるかは、最も基本的なコンテキスト(つまり、どのタイプの疑似が使用されているか)から常に簡単に決定されるため、区別します。(私が気付いていないあいまいな状況がある場合は、コメントで修正してください-知りたいです!)。
それでは、文字列とセレクターの区別がないことが単なる実装の詳細である場合、なぜその:eq(...)
ような選択を明示的に拒否するなどの疑似が行われるのでしょうか。
答えは簡単です。実際にはそうではありません。少なくとも、jQuery1.8.1の時点ではありません。[編集: jQuery 1.8.2の時点では、まったく機能していません。「位置的」疑似の引数は、他のものと同じように引用できます。1.8.1の実装の詳細に関する以下の注記は、歴史的な好奇心として残されています]
次のような関数は次のよう:eq(...)
に実装されます。
"eq": function( elements, argument, not ) {
var elem = elements.splice( +argument, 1 );
return not ? elements : elem;
}
引数を受け取った時点で:eq(...)
は、それはまだ裸の引数(引用符とすべて)の形式になっています。とは異なり、この引数はフェーズ:not(...)
を通過しません。compile(...)
無効な引数の「拒否」は、実際には
+argument
、を介したショートカットキャストによるものです。これにより、NaN
引用符で囲まれた文字列が生成されます(これにより、何にも一致しなくなります)。これはさらに別の実装の詳細ですが、この場合は「正しく」動作します(ここでも、私が知る限り、そのような関数に対する非数値引数が実際に一致する必要がある状況はありますか?)
編集: jQuery 1.8.2の時点で、物事は多少リファクタリングされており、「位置」疑似は「生」引数を受け取らなくなりました。その結果、引用符で囲まれた引数がなどで受け入れられる:eq(...)
ようになりました。この変更は、別のバグ修正の副作用であるように見えます。これは、 af8206ff ..の変更ログに引用符で囲まれた引数のサポートが記載されていないためです。これは、jQueryのバグ#12303の処理エラー:first
:last
を修正することを目的としています。このコミットは、git bisect
と比較的単純なphantomjsスクリプトを使用して検出されました。e89d06c4でSizzleを書き直した後、Sizzleが次のようなセレクターに対して単にサイレントに失敗するわけではないことは注目に値します。:eq("3")
、実際には例外がスローされます。:eq("3")
これは、サポートが意図された動作ではないというさらに多くの証拠と見なされるべきです。
カスタムフィルターに関しては確かに論理的根拠があり、その引数は、評価される方法に応じて、表面的にどのように見えても、場合によっては文字列、場合によってはセレクターと見なすことができます...しかし、その多くは近づいています衒学者。少なくとも区別がないことで、文字列表現を期待する関数を呼び出すときに、物事が簡単になると言えば十分です。
要するに、全体の状況は実装の詳細と考えることができ、セレクターが最初に文字列として渡されるという事実に根ざしています(他にどのようにそれらをSizzleに入れるのですか?)。