Analisis berikut adalah berdasarkan versi jQuery-1.10.2.js.
Yang berikut akan mengambil $("div:not(.class:contain('span')):eq(3)") sebagai contoh untuk menerangkan cara kod tokenize dan preFilter diselaraskan untuk melengkapkan penghuraian. Jika anda ingin mengetahui penjelasan terperinci bagi setiap baris kod kaedah tokenize dan kelas preFilter, sila rujuk dua artikel berikut:
http://www.jb51.net/article/63155.htm
http://www.jb51.net/article/63163.htm
Berikut ialah kod sumber kaedah tokenize, saya telah mengalih keluar semua kod yang berkaitan dengan caching, pemadanan koma dan pemadanan aksara relasi, hanya meninggalkan kod teras yang berkaitan dengan contoh semasa. Kod yang telah dialih keluar adalah sangat mudah Jika perlu, anda boleh membaca artikel di atas.
Selain itu, kod ditulis di atas teks penerangan.
manakala (sejauh ini) {
jika (! padan) {
groups.push(token = []);
}
dipadankan = palsu;
untuk (taip dalam Expr.filter) {
Jika ((match = matchExpr[type].exec(soFar))
&& (!preFilters[type] || (match = preFilters[type]
(perlawanan)))) {
Dipadankan = match.shift();
tokens.push({
Nilai: sepadan,
Taip : taip,
padanan: padanan
});
SoFar = soFar.slice(matched.length);
}
}
jika (! padan) {
Rehat;
}
}
return parseOnly ? soFar.length : soFar ?
tokenCache(pemilih, kumpulan).slice(0);
}
Apabila memasuki gelung while buat kali pertama, memandangkan nilai yang dipadankan belum diberikan, badan penyata berikut dalam if dilaksanakan Penyataan ini akan memulakan pembolehubah token dan menolak token ke dalam tatasusunan kumpulan.
perlawanan =["div", "div"]
Pemilih pertama dalam contoh ialah div, yang sepadan dengan ungkapan biasa matchExpr["TAG"] dan preFilters["TAG"] tidak wujud, jadi badan pernyataan dalam if dilaksanakan.
Buat objek baharu { nilai: "div", taip: "TAG", padankan: ["div"] } dan tolak objek ke dalam tatasusunan token.
Pembolehubah soFar memadamkan div Pada masa ini, soFar=":not(.class:contain('span')):eq(3)"
Gelung kedua untuk: Ambil elemen kedua "CLASS" daripada Expr.filter dan tetapkan ia kepada pembolehubah jenis, dan laksanakan kod badan gelung.
Memandangkan soFar=":not(.class:contain('span')):eq(3)" semasa tidak sepadan dengan ungkapan biasa jenis CLASS, gelung ini tamat.
Yang ketiga untuk gelung: Ambil elemen ketiga "ATTR" daripada Expr.filter dan tetapkan ia kepada pembolehubah jenis, dan laksanakan kod badan gelung.
Begitu juga, memandangkan baki pemilih semasa bukan pemilih atribut, kitaran ini tamat.
Gelung keempat untuk: Ambil elemen keempat "CHILD" daripada Expr.filter dan tetapkan ia kepada pembolehubah jenis dan laksanakan kod badan gelung.
Begitu juga, memandangkan baki pemilih semasa bukan pemilih KANAK-KANAK, kitaran ini tamat.
Gelung kelima untuk: Ambil elemen kelima "PSEUDO" daripada Expr.filter dan tetapkan ia kepada pembolehubah jenis dan laksanakan kod badan gelung.
Keputusan pelaksanaan perlawanan = matchExpr[type].exec(soFar) adalah seperti berikut:
[":not(.class:contain('span')):eq(3)", "not", ".class:contain('span')):eq(3", undefined, undefined, undefined, undefined , undefined, undefined, undefined, undefined]
Memandangkan preFilters["PSEUDO"] wujud, kod berikut dilaksanakan:
preFilters["PSEUDO"] adalah seperti berikut:
jika (matchExpr["KANAK"].test(match[0])) {
kembalikan null;
}
jika (perlawanan[3] && padankan[4] !== tidak ditentukan) {
padan[2] = padanan[4];
} lain jika (tidak disebut
&& rpseudo.test(tidak disebut)
&& (lebihan = tokenize(tidak disebut, benar))
&& (lebihan = unquoted.indexOf(")", unquoted.length
- lebihan)
- tidak disebut.panjang)) {
padan[0] = padankan[0].slice(0, excess);
padanan[2] = unquoted.slice(0, excess);
}
kembalikan perlawanan.slice(0, 3);
}
Parameter padanan yang dihantar adalah sama dengan:
tidak dipetik = ".class:contain('span')):eq(3"
Salin kod
perlawanan = ["kelas" , "kelas"]
Memandangkan preFilters["CLASS"] tidak wujud, badan pernyataan dalam if dilaksanakan.
Salin kod
Buat objek baharu { value: "class", type: "CLASS", padankan: ["class"] } dan tolak objek ke dalam tatasusunan token.
Yang ketiga untuk gelung: Ambil elemen ketiga "ATTR" daripada Expr.filter dan tetapkan ia kepada pembolehubah jenis, dan laksanakan kod badan gelung.
Begitu juga, memandangkan baki pemilih semasa bukan pemilih atribut, kitaran ini tamat.
Begitu juga, memandangkan baki pemilih semasa bukan pemilih KANAK-KANAK, kitaran ini tamat.
[":contain('span')", "contain", "'span'", "'", "span", undefined, undefined, undefined, undefined, undefined, undefined]
Oleh kerana ":contain('span')" tidak sepadan dengan ungkapan biasa matchExpr["CHILD"], badan pernyataan dalaman tidak dilaksanakan.
Memandangkan padanan[3] = "'" dan padanan[4] ="span", badan pernyataan if dalaman dilaksanakan dan "span" ditugaskan untuk memadankan[2]
Pada masa ini, kembali ke gelung untuk kaedah tokenize untuk meneruskan pelaksanaan Pada masa ini, nilai setiap pembolehubah adalah seperti berikut:
soFar = ":contain('span')):eq(3"
":contain('span')", taip:"PSEUDO", padankan: ["contain", "span"] }, dan tolak objek ke dalam tatasusunan token.
Salin kod
Salin kod
Salin kod
Mengembalikan salinan tiga elemen pertama dalam perlawanan.
Kembali ke fungsi tokenize, sekarang padankan = [":not(.class:contain('span'))", "not", ".class:contain('span')"]
padan = ["bukan", ".class:contain('span')"]
kumpulan[0][1] = {nilai: ":not(.class:contain('span'))", taip: "PSEUDO", padanan: ["not", ".class:contain(' span')"] }
kumpulan[0][2] = {nilai: ":eq(3)", jenis: "PSEUDO", padankan: ["eq", "3"] }