Penjelasan terperinci tentang paradigma pengaturcaraan dalam jQuery_jquery

WBOY
Lepaskan: 2016-05-16 16:27:01
asal
1480 orang telah melayarinya

Artikel ini menganalisis paradigma pengaturcaraan dalam jQuery secara terperinci. Kongsikan dengan semua orang untuk rujukan anda. Butirannya adalah seperti berikut:

Wajah pengaturcaraan bahagian hadapan penyemak imbas telah mengalami perubahan yang mendalam sejak tahun 2005. Ini tidak bermakna bahawa sejumlah besar perpustakaan asas dengan fungsi yang kaya telah muncul, membolehkan kami menulis kod perniagaan dengan lebih mudah merupakan perubahan besar dalam cara kita melihat teknologi hadapan, dengan kesedaran yang jelas tentang cara untuk melancarkan produktiviti pengaturcara dengan cara khusus hadapan. Di sini, kami akan memberikan pengenalan ringkas kepada paradigma pengaturcaraan dan teknik biasa yang muncul dalam JavaScript berdasarkan prinsip pelaksanaan kod sumber jQuery.

1. AJAX: keadaan kegigihan, kemas kini tak segerak

Pertama, sedikit sejarah.

A. Pada tahun 1995, Brendan Eich dari Netscape membangunkan bahasa JavaScript, yang merupakan bahasa skrip berasaskan prototaip yang dinamik, ditaip lemah.
B. Pada tahun 1999, Microsoft IE5 telah dikeluarkan, yang termasuk kawalan XMLHTTP ActiveX.
C. Microsoft IE6 telah dikeluarkan pada tahun 2001, sebahagiannya menyokong standard DOM tahap 1 dan CSS 2.
D. Douglas Crockford mencipta format JSON pada tahun 2002.

Pada ketika ini, boleh dikatakan bahawa elemen teknikal yang mana Web 2.0 bergantung pada dasarnya telah terbentuk, tetapi ia tidak serta-merta memberi kesan yang ketara kepada keseluruhan industri. Walaupun beberapa teknik "pemuatan semula halaman separa tak segerak" diedarkan secara rahsia di kalangan pengaturcara, malah melahirkan perpustakaan kelas yang besar dan besar seperti bindows, secara amnya, bahagian hadapan dianggap sebagai paya yang tandus dan kotor, dengan hanya teknologi Backend yang menjadi raja. Apa yang hilang?

Apabila kita melihat kembali kod js sebelum 2005 dari perspektif hari ini, termasuk yang ditulis oleh mereka yang berbakat pada masa itu, kita dapat merasakan dengan jelas kelemahan mereka dalam kawalan program. Bukannya teknologi js sebelum tahun 2005 mempunyai masalah dengan sendirinya, cuma ia bertaburan di peringkat konseptual, tidak mempunyai konsep yang bersatu, atau tidak mempunyai gaya dan jiwa unik mereka sendiri. Pada masa itu, kebanyakan orang dan kebanyakan teknologi cuba mensimulasikan bahasa berorientasikan objek tradisional dan menggunakan teknologi berorientasikan objek tradisional untuk melaksanakan tiruan model GUI tradisional.

2005 adalah tahun perubahan dan tahun penciptaan konsep. Dengan keluaran satu siri aplikasi interaktif yang menyegarkan oleh Google, artikel "Ajax: A New Approach to Web Applications" oleh Jesse James Garrett telah diedarkan secara meluas. Ajax, konsep khusus front-end, dengan cepat menyatukan banyak amalan bertaburan di bawah slogan yang sama, mencetuskan anjakan paradigma dalam pengaturcaraan Web. Seperti kata pepatah, jika nama tidak betul, kata-kata tidak akan betul Sekarang orang yang tidak dikenali boleh mencari organisasi. Sebelum Ajax, orang ramai telah lama menyedari bahawa ciri penting seni bina B/S ialah ruang keadaan pelayar dan pelayan telah dipisahkan Walau bagaimanapun, penyelesaian umum adalah untuk menyembunyikan perbezaan ini dan menyegerakkan keadaan latar depan ke latar belakang. Pemprosesan logik bersatu, seperti ASP.NET. Oleh kerana kekurangan corak reka bentuk matang untuk menyokong kegigihan keadaan latar depan, objek js yang dimuatkan akan dipaksa untuk dibuang apabila menukar halaman Dengan cara ini, siapa yang boleh mengharapkan ia menyelesaikan sebarang kerja yang rumit?

Ajax dengan jelas menyatakan bahawa antara muka sebahagiannya dimuat semula dan keadaan berada di latar depan, yang menggalakkan keperluan: objek js perlu wujud di latar depan untuk masa yang lebih lama. Ini juga bermakna keperluan untuk mengurus objek dan fungsi ini dengan berkesan, yang bermaksud teknologi organisasi kod yang lebih kompleks, yang bermaksud keinginan untuk modulariti dan asas kod biasa.

Sebenarnya terdapat sangat sedikit bahagian kod sedia ada jQuery yang sebenarnya berkaitan dengan Ajax (menggunakan kawalan XMLHTTP untuk mengakses data pemulangan latar belakang secara tidak segerak), tetapi tanpa Ajax, jQuery tidak akan mempunyai sebab untuk wujud sebagai pangkalan kod awam.

2. Modularisasi: mengurus ruang nama

Apabila sejumlah besar kod dijana, konsep paling asas yang kita perlukan ialah modularisasi, iaitu mengurai dan menggunakan semula kerja. Kunci kepada kerja reput ialah hasil kerja bebas setiap orang boleh disepadukan bersama. Ini bermakna setiap modul mesti berdasarkan konsep asas yang konsisten dan boleh berinteraksi Maksudnya, ia harus berdasarkan asas kod biasa, melindungi ketidakkonsistenan pelayar asas dan melaksanakan lapisan abstraksi bersatu, seperti a. mekanisme pengurusan acara bersatu. Lebih penting daripada asas kod bersatu, mesti tiada percanggahan nama antara modul. Jika tidak, kedua-dua modul tidak akan berfungsi bersama walaupun tanpa sebarang interaksi antara mereka.

Salah satu titik jualan utama yang dipromosikan oleh jQuery pada masa ini ialah kawalannya yang baik ke atas ruang nama. Ini lebih penting daripada menyediakan titik fungsi yang lebih dan lebih lengkap. Modulariti yang baik membolehkan kami menggunakan semula kod dari mana-mana sumber, dan kerja semua orang boleh dikumpul dan ditindih. Dan pelaksanaan fungsi hanyalah masalah beban kerja sementara. jQuery menggunakan varian corak modul untuk mengurangkan kesan pada ruang nama global, hanya menambah objek jQuery (iaitu, $fungsi) pada objek tetingkap.

Kod corak modul yang dipanggil adalah seperti berikut. Kuncinya ialah menggunakan fungsi tanpa nama untuk mengehadkan skop pembolehubah sementara.

Salin kod Kod adalah seperti berikut:
ciri var =(fungsi() {

//Pembolehubah dan fungsi peribadi
var privateThing = 'rahsia',
PublicThing = 'bukan rahsia',

changePrivateThing = function() {
        privateThing = 'rahsia super';
},

sayPrivateThing = function() {
console.log(privateThing);
         changePrivateThing();
};

// Kembali ke API awam
kembali {
PublicThing : publicThing,
sayPrivateThing : sayPrivateThing
}
})();

JS sendiri tidak mempunyai struktur pakej, tetapi selepas percubaan selama bertahun-tahun, industri secara beransur-ansur menyatukan pemahamannya tentang pemuatan pakej, membentuk penyelesaian seperti perpustakaan RequireJs yang telah mendapat konsensus tertentu. jQuery boleh disepadukan dengan baik dengan perpustakaan RequireJS untuk mencapai pengurusan pergantungan modul yang lebih lengkap. http://requirejs.org/docs/jquery.html

Salin kod Kod adalah seperti berikut:
memerlukan(["jquery", "jquery.my"], fungsi () {
//Laksanakan apabila kedua-dua jquery.js dan jquery.my.js berjaya dimuatkan
$(fungsi(){
$('#my').myFunc();
});
});


Modul saya/baju ditakrifkan melalui panggilan fungsi berikut, yang bergantung pada modul saya/troli dan saya/inventori,
Salin kod Kod adalah seperti berikut:
require.def("my/shirt",
["saya/troli", "saya/inventori"],
Fungsi(troli, inventori) {
// Gunakan corak modul di sini untuk mengembalikan API yang didedahkan oleh modul saya/baju
         kembali {
            warna: "biru",
saiz: "besar"
                addToCart: function() {
// penurunan ialah API yang didedahkan oleh saya/inventori
Inventori.penurunan(ini);
                  troli. tambah(ini);
            }
}
}
);

3. Magic$: Promosi objek

Apakah yang anda fikirkan apabila anda mula-mula melihat fungsi $? Teori pengaturcaraan tradisional sentiasa memberitahu kita bahawa penamaan fungsi harus tepat dan harus menyatakan dengan jelas niat pengarang malah ia mendakwa bahawa nama panjang adalah lebih baik daripada nama pendek kerana ia mengurangkan kemungkinan kekaburan. Tetapi apakah $? Kod bercelaru? Mesej yang disampaikannya terlalu kabur dan samar-samar. $ telah dicipta oleh perpustakaan prototype.js dan benar-benar fungsi ajaib kerana ia boleh meningkatkan nod DOM primitif menjadi objek dengan tingkah laku yang kompleks. Dalam pelaksanaan asal prototype.js, fungsi $ ditakrifkan sebagai

Salin kod Kod adalah seperti berikut:
var $ = function (id) {
Kembalikan "string" == typeof id ? document.getElementById(id) : id;
};

Ini pada asasnya sepadan dengan formula berikut
e = $(id)

Ini bukan sahaja singkatan nama fungsi yang bijak, tetapi yang lebih penting, ia mewujudkan korespondensi satu-dengan-satu antara id teks dan elemen DOM pada peringkat konsep. Sebelum ada $, jarak antara id dan elemen yang sepadan secara amnya, elemen perlu dicache dalam pembolehubah, seperti

Salin kod Kod adalah seperti berikut:
var ea = document.getElementById('a');
var eb = document.getElementById('b');
ea.style....

Tetapi selepas menggunakan $, anda boleh melihat tulisan berikut di mana-mana
Salin kod Kod adalah seperti berikut:
$('header_' id).style...
$('body_' id)....

Jarak antara id dan elemen nampaknya telah dihapuskan dan ia boleh saling berkait rapat.

prototype.js kemudiannya mengembangkan makna $,

Salin kod Kod adalah seperti berikut:
fungsi $() {
elemen var = new Array();
 
untuk (var i = 0; i < arguments.length; i ) {
         elemen var = argumen[i];
Jika (jenis elemen == 'rentetan')
            elemen = document.getElementById(elemen);
 
            jika (hujah. panjang == 1)
           elemen pulangan;
 
        elemen.push(elemen);
}
 
Kembalikan elemen;
}

Ini sepadan dengan formula:
[e,e] = $(id,id)

Malangnya, prototype.js tersasar dalam langkah ini, dan pendekatan ini mempunyai sedikit nilai praktikal.
Ia adalah jQuery yang benar-benar mempromosikan $, dan $nya sepadan dengan formula
[o] = $(pemilih)
Berikut ialah tiga peningkatan:
A. Pemilih bukan lagi pengesan nod tunggal, tetapi pemilih koleksi yang kompleks
B. Elemen yang dikembalikan bukanlah nod DOM asal, tetapi objek dengan gelagat kaya yang dipertingkatkan lagi oleh jQuery, yang boleh memulakan rantai panggilan fungsi yang kompleks.
C. Objek pembungkusan yang dikembalikan oleh $ dibentuk menjadi bentuk tatasusunan, yang secara semula jadi menyepadukan operasi pengumpulan ke dalam rantaian panggilan.

Sudah tentu, perkara di atas hanyalah penerangan yang terlalu ringkas tentang $ ajaib, dan fungsi sebenar adalah lebih rumit, khususnya, terdapat fungsi pembinaan langsung yang sangat biasa digunakan

Salin kod Kod adalah seperti berikut:
$("
".....
jQuery secara langsung akan membina satu siri nod DOM berdasarkan teks html masuk dan membungkusnya sebagai objek jQuery Ini boleh dilihat sebagai lanjutan pemilih pada tahap tertentu: perihalan kandungan html itu sendiri adalah sebutan Unik.

$(fungsi{}) Fungsi ini benar-benar tidak bersuara Ini bermakna fungsi panggil balik ini dipanggil apabila document.ready. Sungguh, $ adalah fungsi ajaib Jika anda mempunyai sebarang soalan, sila tanya.

Ringkasnya, $ ialah saluran peralihan daripada DOM biasa dan dunia penerangan teks kepada dunia jQuery dengan gelagat objek kaya. Selepas melintasi pintu ini, kami tiba di Utopia.



4. Parameter amorf: fokus pada ekspresi dan bukannya kekangan

Memandangkan bahasa yang ditaip lemah mempunyai perkataan "lemah" di kepala mereka, tidak dapat dielakkan bahawa orang akan berasa sedikit kekurangan secara semula jadi Adakah kekurangan kekangan jenis dalam program itu benar-benar kelemahan utama dalam bahasa tradisional yang ditaip dengan kuat , jenis dan bilangan parameter fungsi adalah semua kekangan yang diperiksa oleh pengkompil, tetapi kekangan ini masih jauh dari mencukupi Dalam aplikasi umum, untuk mengukuhkan kekangan, sejumlah besar kod pertahanan sentiasa ditambah, seperti dalam C We. biasa menggunakan ASSERT, dan dalam java kita sering perlu menentukan julat nilai parameter


Salin kod Kod adalah seperti berikut:
jika (indeks < 0 || indeks >= saiz)
           buang IndexOutOfBoundsException baharu(
"Indeks: " indeks ", Saiz: " saiz);

Jelas sekali, kod ini akan membawa kepada sejumlah besar laluan pelaksanaan tidak berfungsi dalam program, iaitu, kami telah membuat banyak pertimbangan, dan apabila kod itu dilaksanakan ke titik tertentu, sistem mengeluarkan pengecualian, menjerit bahawa laluan ini disekat. Jika kita mengubah pemikiran kita, kerana kita mempunyai Selepas membuat pertimbangan tertentu, bolehkah kita menggunakan hasil pertimbangan ini untuk melakukan sesuatu bahasa yang ditaip lemah Ia tidak boleh mengekang jenis parameter secara automatik dan melemahkan lagi bentuk parameter, ia akan "Kelemahan" telah ditolak ke tahap yang melampau Apabila tiada apa-apa yang lemah untuk dilakukan, akan menjadi ciri ikonik? Lihat fungsi mengikat acara mengikat dalam jQuery,

A. Ikat satu acara pada satu masa

Salin kod Kod adalah seperti berikut:
$("#my") .bind(" mouseover", function(){});
B. Ikat berbilang acara pada satu masa
Salin kod Kod adalah seperti berikut:
$("#my") .bind( "mouseover mouseout",function(){})
C. Tukar borang dan ikat berbilang acara

Salin kod Kod adalah seperti berikut:
$("#my").bind({mouseover:function( ){} , mouseout:function(){});
D. Ingin menghantar beberapa parameter kepada pendengar acara

Salin kod Kod adalah seperti berikut:
$('#my').bind('click', { foo: " xxxx"}, fungsi(acara) { event.data.foo..})
E. Ingin mengumpulkan pendengar acara

Salin kod Kod adalah seperti berikut:
$("#my").bind("click.myGroup" , function( ){});
F. Mengapa fungsi ini tidak menjadi gila???

Walaupun jenisnya tidak pasti, makna parameter pada kedudukan tetap mesti pasti, bukan? ini?
Nilai nilai = o.val(), tetapkan nilai o.val(3)

       
Bagaimana fungsi itu boleh menjadi sangat berlebihan, bagaimana ia boleh bertindak secara berbeza bergantung pada jenis dan bilangan parameter yang dilalui? . Walaupun ada banyak bentuk Perubahan, tetapi tidak ada kata-kata yang tidak masuk akal

5. Operasi rantai: penghalusan berperingkat linearisasi
Titik jualan utama jQuery pada zaman awal ialah operasi rantaian yang dipanggil


Salin kod Kod adalah seperti berikut: $('#content') // Cari elemen kandungan
.find('h3') // Pilih semua nod h3 keturunan
.eq(2) // Tapis koleksi dan kekalkan elemen ketiga
​​​​.html('Tukar teks h3 ketiga')
.end() // Kembali ke koleksi h3 sebelumnya
.eq(0)
​​​​.html('Tukar teks h3 pertama');

Dalam bahasa imperatif umum, kami sentiasa perlu menapis data dalam gelung bersarang, dan kod untuk benar-benar mengendalikan data terikat dengan kod untuk mencari data Walau bagaimanapun, jQuery menggunakan kaedah membina koleksi dahulu dan kemudian memohon berfungsi kepada koleksi. Kaedah ini mencapai penyahgandingan dua logik dan linearisasi struktur bersarang Malah, kita boleh memahami koleksi secara intuitif tanpa menggunakan pemikiran prosedur, seperti $('div.my input:checked') Boleh dilihat sebagai penerangan langsung dan bukannya penjejakan kelakuan proses.

Gelung bermaksud pemikiran kita berada dalam keadaan gulung semula berulang, dan selepas linearisasi, ia berjalan terus ke satu arah, yang sangat mengurangkan beban pemikiran dan meningkatkan kebolehkomposisian kod untuk mengurangkan gangguan panggilan chain , jQuery mencipta idea yang menarik: jQuery membungkus objek itu sendiri seperti tatasusunan (koleksi boleh dipetakan ke koleksi baharu, dan koleksi boleh dihadkan kepada subkoleksi mereka sendiri Pemula panggilan itu ialah koleksi). Hasilnya juga merupakan koleksi. Beberapa perubahan struktur telah berlaku, tetapi ia masih merupakan satu set adalah titik tetap konseptual. Ini adalah idea reka bentuk yang diserap daripada bahasa berfungsi. Operasi pengumpulan adalah operasi yang terlalu biasa Di Java, kita boleh dengan mudah mendapati bahawa sebilangan besar fungsi enkapsulasi sebenarnya merangkumi beberapa operasi traversal koleksi Dalam jQuery, operasi pengumpulan terlalu mudah dan tidak perlu dikapsulkan.

Panggilan berangkai bermakna kami sentiasa mempunyai objek "semasa", dan semua operasi dilakukan pada objek semasa ini. Ini sepadan dengan formula berikut
x = dx
Setiap langkah dalam rantai panggilan ialah penerangan tambahan bagi objek semasa dan proses penghalusan langkah demi langkah ke arah matlamat akhir. Idea ini juga digunakan secara meluas dalam platform Witrix. Terutama untuk merealisasikan penyepaduan mekanisme platform dan kod perniagaan, platform akan menyediakan kandungan lalai objek (bekas), dan kod perniagaan boleh diperhalusi dan disemak secara beransur-ansur atas dasar ini, termasuk membatalkan tetapan lalai.

Bercakap mengenainya, walaupun panggilan berantai jQuery sangat mudah di permukaan, anda perlu menulis lapisan tambahan gelung apabila melaksanakannya secara dalaman, kerana pengkompil tidak tahu tentang "menggunakan secara automatik pada setiap elemen dalam koleksi".

Salin kod Kod adalah seperti berikut:
$.fn['someFunc'] = function(){
Kembalikan this.each(function(){
​​jQuery.someFunc(ini,...);
}
}


6. pengurusan data bersepadu

Sebagai perpustakaan js, masalah besar yang mesti diselesaikannya ialah perkaitan keadaan dan pengurusan kolaboratif antara objek js dan nod DOM. Sesetengah perpustakaan js memilih untuk memfokus pada objek js dan menyimpan penunjuk nod DOM dalam pembolehubah ahli objek js Apabila mengakses, mereka sentiasa menggunakan objek js sebagai titik masuk dan secara tidak langsung mengendalikan objek DOM melalui fungsi js. Di bawah pengkapsulan jenis ini, nod DOM sebenarnya hanyalah "himpunan" peringkat rendah yang dipaparkan sebagai antara muka. Pilihan jQuery adalah serupa dengan platform Witrix, yang berdasarkan struktur HTML itu sendiri Ia meningkatkan fungsi nod DOM melalui js dan mempromosikannya kepada objek lanjutan dengan tingkah laku yang kompleks. Idea di sini ialah reka bentuk yang tidak mengganggu dan kemerosotan yang anggun. Struktur semantik lengkap pada peringkat HTML asas Peranan js adalah untuk meningkatkan tingkah laku interaktif dan mengawal borang persembahan.

Jika kita mengakses objek pembungkusan yang sepadan melalui $('#my') setiap kali, di manakah beberapa pembolehubah keadaan yang perlu dikekalkan untuk masa yang lama disimpan? jQuery menyediakan mekanisme pengurusan data global yang bersatu.

Dapatkan data:

Salin kod Kod adalah seperti berikut:
$('#my').data ('myAttr ')

Tetapkan data:
Salin kod Kod adalah seperti berikut:
$('#my').data('myAttr ',3 );

Mekanisme ini secara semula jadi menyepadukan pemprosesan atribut data HTML5
Salin kod Kod adalah seperti berikut:

Set data dalam HTML boleh dibaca melalui $('#my').data('myAttr').

Apabila mengakses data buat kali pertama, jQuery akan menetapkan uuid unik pada nod DOM, dan kemudian menetapkannya pada atribut expando khusus bagi nod DOM memastikan uuid ini tidak berulang dalam halaman ini.

Salin kod Kod adalah seperti berikut:
elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];

Kod di atas boleh mengendalikan kedua-dua nod DOM dan objek js tulen. Jika ia adalah objek js, data diletakkan terus dalam objek js itu sendiri, dan jika ia adalah nod DOM, ia diuruskan secara seragam melalui cache.

Oleh kerana semua data diurus secara seragam melalui mekanisme data, terutamanya semua fungsi mendengar acara (data.events), jQuery boleh melaksanakan pengurusan sumber dengan selamat. Apabila mengklon nod, fungsi mendengar acara yang berkaitan boleh diklon secara automatik. Apabila kandungan nod DOM diganti atau nod DOM dimusnahkan, jQuery juga boleh membatalkan fungsi mendengar acara secara automatik dan mengeluarkan data js yang berkaitan dengan selamat.

7 acara: model acara bersatu

Gambar "peristiwa yang merambat di sepanjang pokok objek" adalah intipati model pengaturcaraan antara muka berorientasikan objek. Komposisi objek membentuk perihalan struktur antara muka yang stabil Peristiwa berterusan berlaku pada nod tertentu pokok objek dan merambat ke atas melalui mekanisme menggelegak. Pokok objek secara semula jadi menjadi struktur kawalan Kita boleh mendengar peristiwa pada semua nod anak pada nod induk tanpa mewujudkan perkaitan dengan setiap nod anak.

Selain mewujudkan abstraksi bersatu untuk model acara penyemak imbas yang berbeza, jQuery terutamanya telah membuat peningkatan berikut:
A. Menambah mekanisme peristiwa tersuai (tersuai) Mekanisme penyebaran peristiwa tidak ada kaitan dengan kandungan acara itu sendiri pada dasarnya, jadi acara tersuai boleh melalui laluan pemprosesan yang sama dan menggunakan kaedah pemantauan yang sama seperti peristiwa terbina dalam penyemak imbas. . Gunakan Peristiwa tersuai boleh meningkatkan kohesi kod dan mengurangkan gandingan kod Contohnya, jika tiada acara tersuai, kod yang berkaitan selalunya perlu mengendalikan objek berkaitan

Salin kod Kod adalah seperti berikut:
$('.switch, .clapper').click(function( ) {
var $light = $(this).parent().find('.lightbulb');
Jika ($light.hasClass('on')) {
          $light.removeClass('on').addClass('off');
} lain {
         $light.removeClass('off').addClass('on');
}
});

Jika anda menggunakan acara tersuai, semantik yang dinyatakan adalah lebih terkawal dan jelas,
Salin kod Kod adalah seperti berikut:
$('.switch, .clapper').click(function( ) {
$(this).parent().find('.lightbulb').trigger('changeState');
});

B. Pemantauan acara tambahan untuk nod yang dibuat secara dinamik Fungsi bind hanya boleh mendaftarkan fungsi mendengar kepada nod DOM sedia ada, Contohnya,
Salin kod Kod adalah seperti berikut:
$('li.trigger').bind('click', function() {}}

Jika nod li lain dibuat selepas memanggil bind, peristiwa klik nod ini tidak akan dipantau.

Mekanisme perwakilan jQuery boleh mendaftarkan fungsi mendengar kepada nod induk, dan peristiwa yang dicetuskan pada nod anak akan dihantar secara automatik kepada pengendali Fn yang sepadan mengikut pemilih Dengan cara ini, jika anda mendaftar sekarang, anda boleh mendengarnya nod yang dicipta pada masa hadapan

Salin kod Kod adalah seperti berikut:
$('#myList').delegate('li.trigger' , 'klik', pengendaliFn);
Baru-baru ini, jQuery 1.7 telah menyatukan mekanisme bind, live dan delegate, dan dunia disatukan, hanya hidup/mati.


Salin kod Kod adalah seperti berikut:
$('li.trigger').on('click', handlerFn); // Setara dengan mengikat
$('#myList').on('click', 'li.trigger', handlerFn); // Setara dengan mewakilkan

 
8. Barisan Animasi: Penyelarasan Jam Global

Mengetepikan pelaksanaan jQuery, pertimbangkan dahulu apa yang perlu kita lakukan jika kita ingin mencapai kesan animasi pada antara muka Sebagai contoh, kita ingin meningkatkan lebar div daripada 100px kepada 200px dalam masa 1 saat mudah untuk membayangkan bahawa dalam satu tempoh masa kita perlu melaraskan lebar div dari semasa ke semasa, [dan pada masa yang sama] kita juga perlu melaksanakan kod lain Tidak seperti panggilan fungsi biasa, selepas mengeluarkan arahan animasi, kita tidak boleh mengharapkan untuk mendapatkan apa yang kita mahu serta-merta Hasilnya, dan kita tidak boleh hanya menunggu keputusan tiba Kerumitan animasi terletak pada ia mesti dilaksanakan dalam tempoh masa selepas ungkapan sekali sahaja, dan terdapat. berbilang laluan pelaksanaan logik yang perlu dibuka pada masa yang sama

Sir Isaac Newton yang hebat menulis dalam "Prinsip Matematik Falsafah Semula Jadi": "Masa mutlak, benar dan matematik itu sendiri berlalu". A1 ke A5 dan langkah B1 ke B5 pada masa yang sama, kita hanya perlu melaksanakan [A1, B1] pada masa t1, [A2, B2] pada masa t2, dan seterusnya t1 |. t2 |. t4 | A1 |. A2 |. A4 | B1 |. B3 |

Borang pelaksanaan khusus boleh menjadi
A. Bagi setiap animasi, bahagikannya kepada objek Animasi, yang dibahagikan kepada beberapa langkah secara dalaman.
animasi = Animasi baharu(div,"lebar",100,200,1000,
Fungsi interpolasi yang bertanggungjawab untuk segmentasi langkah, fungsi panggil balik apabila animasi selesai); B. Daftarkan objek animasi dalam pengurus global

timerFuncs.add(animasi);

C. Pada setiap detik pencetus jam global, majukan setiap urutan pelaksanaan yang didaftarkan selangkah lebih jauh, dan jika ia telah tamat, padamkannya daripada pengurus global.




Salin kod

Setelah menyelesaikan masalah prinsip, mari kita lihat masalah ekspresi Bagaimana untuk mereka bentuk fungsi antara muka untuk menyatakan niat kita dalam bentuk yang paling padat yang sering kita perlu hadapi:

A. Terdapat berbilang elemen untuk melaksanakan animasi yang serupa
B. Setiap elemen mempunyai berbilang atribut yang perlu diubah pada masa yang sama C. Selepas melaksanakan satu animasi, mulakan animasi lain

Jawapan jQuery kepada soalan-soalan ini boleh dikatakan memerah nilai terakhir ungkapan tatabahasa js



Salin kod

Kod adalah seperti berikut:$('input') .animate({left:' =200px',top:'300'},2000) .animate({left:'-=200px',top:20},1000) .queue(function(){ //Di sini dequeue akan mula-mula melaksanakan fungsi seterusnya dalam baris gilir, jadi alert("y")
         $(this).dequeue();
makluman('x');
})
.queue(function(){
makluman("y");
// Jika anda tidak melakukan dequeue secara aktif, pelaksanaan baris gilir akan terganggu dan tidak akan diteruskan secara automatik.
          $(this).dequeue();
});

A. Gunakan mekanisme pemilih terbina dalam jQuery untuk menyatakan pemprosesan koleksi secara semulajadi.
B. Gunakan Peta untuk menyatakan berbilang perubahan atribut
C. Gunakan mikroformat untuk menyatakan konsep delta khusus domain ' =200px' bermakna menambah 200px pada nilai sedia ada
D. Gunakan susunan panggilan fungsi untuk mentakrifkan susunan pelaksanaan animasi secara automatik: animasi yang dilampirkan pada baris gilir pelaksanaan secara semula jadi akan menunggu sehingga animasi sebelumnya dilaksanakan sepenuhnya sebelum bermula.

Butiran pelaksanaan baris gilir animasi jQuery adalah kira-kira seperti berikut,

A. Fungsi animasi sebenarnya memanggil giliran(fungsi(){dequeue perlu dipanggil pada akhir pelaksanaan, jika tidak kaedah seterusnya tidak akan didorong})
Apabila fungsi baris gilir dilaksanakan, jika ia adalah baris gilir fx dan tiada animasi sedang berjalan (jika animasi dipanggil dua kali berturut-turut, fungsi pelaksanaan kedua akan menunggu dalam baris gilir), operasi dequeue akan dicetuskan secara automatik untuk memacu beratur untuk berlari.
Jika ia adalah baris gilir fx, rentetan "sedang berjalan" akan ditambahkan secara automatik ke bahagian atas baris gilir apabila nyah gilir, menunjukkan bahawa animasi akan dilaksanakan
B. Untuk setiap harta, cipta objek jQuery.fx. Kemudian panggil fungsi fx.custom (bersamaan dengan permulaan) untuk memulakan animasi.
C. Dalam fungsi tersuai, daftarkan fungsi fx.step ke timerFuncs global, dan kemudian cuba mulakan pemasa global.
timerId = setInterval( fx.tick, fx.interval );
D. Fungsi tanda statik akan memanggil fungsi langkah setiap fx dalam urutan. Dalam fungsi langkah, nilai semasa atribut dikira melalui pelonggaran, dan kemudian kemas kini fx dipanggil untuk mengemas kini atribut.
E. Fungsi langkah fx menentukan bahawa jika semua perubahan atribut telah selesai, dequeue dipanggil untuk memacu kaedah seterusnya.

Apa yang sangat menarik ialah terdapat banyak kod pencetus geganti dalam kod pelaksanaan jQuery: jika anda perlu melaksanakan animasi seterusnya, keluarkannya dan laksanakannya, jika anda perlu memulakan pemasa, mulakan pemasa, dan lain-lain. Ini kerana program js berbenang tunggal Terdapat hanya satu laluan pelaksanaan yang sebenar Untuk memastikan bahawa utas pelaksanaan tidak terganggu, fungsi perlu membantu antara satu sama lain enjin di dalam program, atau bahkan enjin pelaksanaan yang tidak terhingga, maka penampilan program akan berubah pada dasarnya

9. Corak janji: pengenalpastian hubungan sebab akibat

Pada hakikatnya, sentiasa terdapat begitu banyak garis masa yang berkembang secara bebas, dan orang dan benda bersilang dalam masa dan ruang, tetapi tiada sebab dan akibat berlaku dalam perisian, fungsi disusun dalam kod sumber, dan beberapa soalan pasti akan timbul . Kenapa yang di hadapan harus dibunuh dahulu? ialah teori relativiti . Jika tiada pertukaran maklumat dan tidak saling bergantung, maka peristiwa yang berlaku secara berurutan dalam satu sistem koordinat mungkin kelihatan dalam susunan terbalik apabila dilihat dalam sistem koordinat yang lain , dan kemudian Mencipta corak janji.

Pola janji dan masa depan pada asasnya adalah perkara yang sama Mari kita lihat corak masa depan yang biasa di Jawa.


Salin kod Kod adalah seperti berikut:
futureResult = doSomething();
...
realResult = futureResult.get();
Mengeluarkan panggilan fungsi hanya bermakna sesuatu telah berlaku, dan tidak semestinya pemanggil perlu mengetahui keputusan akhir perkara itu yang dikembalikan dengan segera oleh fungsi itu hanyalah janji (jenis Masa Depan) yang akan ditunaikan masa depan, yang sebenarnya adalah Beberapa jenis pemegang diedarkan, dan kod yang bertukar tangan di tengah-tengah tidak peduli dengan keputusan sebenar dan sama ada ia telah dikembalikan sehingga sekeping kod perlu bergantung keputusan dikembalikan melalui panggilan, jadi ia membuka masa hadapan dan menyemaknya Jika hasil sebenar telah dikembalikan , maka future.get() mengembalikan hasil sebenar dengan serta-merta, jika tidak, ia akan menyekat laluan pelaksanaan semasa sehingga keputusan dikembalikan. Memanggil future.get() selepas itu akan sentiasa kembali serta-merta, kerana hubungan sebab akibat telah diwujudkan, [result return] Peristiwa ini mesti pernah berlaku sebelum ini dan tidak akan berubah lagi.

Mod masa hadapan secara amnya bermaksud objek luaran secara aktif menyemak nilai pulangan masa hadapan, manakala mod janji bermakna objek luaran mendaftarkan fungsi panggil balik pada janji


Salin kod Kod adalah seperti berikut:
fungsi getData(){
Kembalikan $.get('/foo/').done(function(){
console.log('Fires selepas permintaan AJAX berjaya');
}).gagal(fungsi(){
console.log('Fires after the AJAX request fails');
});
}

fungsi showDiv(){
var dfd = $.Deferred();
$('#foo').fadeIn( 1000, dfd.resolve );
Kembalikan dfd.promise();
}

$.when( getData(), showDiv() )
.then(function(ajaxResult, ignoreResultFromShowDiv){
console.log('Fires after BOTH showDiv() AND the AJAX request successful!');
​​​​ // 'ajaxResult' ialah respons pelayan
});

jQuery memperkenalkan struktur Tertunda, membina semula ajax, baris gilir, document.ready, dsb. mengikut mod janji, dan menyatukan mekanisme pelaksanaan tak segerak kemudian(onDone, onFail) akan menambah fungsi panggil balik pada janji panggilan berjaya diselesaikan ( menyelesaikan), fungsi panggil balik onDone akan dilaksanakan, dan jika panggilan gagal (tolak), maka onFail akan dilaksanakan apabila boleh menunggu pada beberapa objek janji telah bermula atau pun tamat, Anda masih boleh mendaftarkan fungsi panggil balik

someObj.done(callback).sendRequest() vs. someObj.sendRequest().done(callback)

Mendaftarkan fungsi panggil balik sebelum mengeluarkan panggilan tak segerak atau mendaftar selepas mengeluarkan panggilan tak segerak adalah setara sepenuhnya Ini mendedahkan bahawa ungkapan program tidak pernah benar-benar tepat dan sentiasa ada dimensi perubahan yang wujud jika dimensi yang wujud ini boleh menjadi berkesan digunakan Kebolehubahan boleh meningkatkan prestasi program serentak.

Pelaksanaan khusus mod janji adalah sangat mudah._Deferred mentakrifkan baris gilir fungsi, yang mempunyai fungsi berikut:

.

A. Simpan fungsi panggil balik.
B. Laksanakan semua fungsi yang disimpan pada masa menyelesaikan atau menolak.
C. Selepas ia dilaksanakan, sebarang fungsi tambahan akan dilaksanakan serta-merta.

Sesetengah bahasa yang berorientasikan khusus kepada pengkomputeran teragih atau pengkomputeran selari akan mempunyai mod janji terbina dalam pada tahap bahasa, seperti bahasa E

Salin kod Kodnya adalah seperti berikut:
def carPromise := carMaker <- produce("Mercedes");
Def temperaturePromise := carPromise <- getEngineTemperature()
...
Apabila (TemperaturePromise) ->           println(`Suhu enjin kereta ialah: $temperature`)
} tangkap e {
          println(`Tidak dapat suhu enjin, ralat: $e`)
}
Dalam bahasa E, <- ialah pengendali akhirnya, yang bermaksud ia akan dilaksanakan akhirnya, tetapi tidak semestinya sekarang Kereta biasa.moveTo(2,3) bermakna ia akan dilaksanakan serta-merta dan hasilnya akan diperolehi pengkompil bertanggungjawab untuk mengenal pasti semua kebergantungan janji Dan secara automatik melaksanakan penjadualan

10 melanjutkan: Warisan tidak perlu
JS ialah bahasa berasaskan prototaip dan tidak mempunyai mekanisme pewarisan terbina dalam Ini selalu mengganggu ramai pelajar yang berpendidikan mendalam dalam pendidikan berorientasikan objek tetapi adakah warisan itu perlu? Jawapan paling mudah ialah: penggunaan semula kod Jadi, mari kita analisa potensi warisan sebagai cara penggunaan semula kod.

Dulu ada konsep yang dipanggil "warisan berbilang", yang merupakan versi Super Saiyan bagi konsep pewarisan Malangnya, ia kemudiannya didiagnosis sebagai mengalami kecacatan kongenital, sehingga tafsiran konsep pewarisan muncul: pewarisan ialah hubungan " ialah satu", objek terbitan "ialah a" mempunyai banyak kelas asas, yang pasti akan membawa kepada skizofrenia, jadi warisan berbilang adalah buruk


Salin kod Kod adalah seperti berikut:kelas A{ public: void f(){ f dalam A } } kelas B{ awam: void f(){ f dalam B } }
kelas D: awam A, B{}

Jika kelas D mewarisi daripada dua kelas asas A dan B, dan kedua-dua kelas A dan B melaksanakan fungsi yang sama f, maka f dalam kelas D ialah f dalam A atau f dalam B, atau adakah ia Bagaimana pula dengan f dalam A dan f dalam B? Kemunculan dilema ini sebenarnya berpunca daripada fakta bahawa kelas asas A dan B dalam hubungan selari Mereka memenuhi undang-undang komutatif dan undang-undang bersekutu. mungkin sukar bagi kita untuk mengenali dua perhubungan Subordinasi akan muncul di antara mana-mana konsep Tetapi jika kita melonggarkan beberapa keperluan tahap konsep dan mempertimbangkan isu penggunaan semula kod lebih daripada peringkat operasi, kita hanya boleh berfikir bahawa B beroperasi berdasarkan A, maka. kita boleh mendapatkan linear Hasil transformasi Dalam erti kata lain, melepaskan undang-undang komutatif antara A dan B dan hanya mengekalkan undang-undang bersekutu, melanjutkan A, B dan melanjutkan B, A akan mempunyai dua keputusan yang berbeza, dan tidak akan ada lagi. menjadi sebarang kekaburan dalam tafsiran Mekanisme sifat yang dipanggil dalam bahasa sebenarnya mengamalkan strategi ini

Lama selepas penciptaan teknologi berorientasikan objek, apa yang dipanggil pengaturcaraan berorientasikan aspek (AOP) muncul ia berbeza daripada OOP kerana ia adalah teknologi penentududukan dan pengubahsuaian dalam ruang struktur kod dan kaedah, dan tidak tahu maksudnya AOP juga menyediakan kaedah penggunaan semula kod yang serupa dengan pewarisan berbilang, iaitu objek dianggap sebagai Peta yang boleh dibuka dan diubah suai dengan sewenang-wenangnya disuntik terus ke dalam badan objek dan terus berubah kelakuannya Pustaka prototype.js memperkenalkan fungsi lanjutan,



Salin kod Kod adalah seperti berikut:Object.extend = function(destination, source) {
untuk (sifat var dalam sumber) {
destinasi[harta] = sumber[harta];
}
Destinasi pulang;
}

ialah operasi penutup antara Peta, tetapi ia sangat berkesan dan telah diperluaskan dalam perpustakaan jQuery Operasi ini serupa dengan mixin, yang merupakan cara teknikal utama penggunaan semula kod dalam jQuery---ia bukan masalah besar. jika tiada harta pusaka.

11 Pemetaan nama: semuanya adalah data

Jika kod itu bagus, perlu ada kurang pertimbangan gelung dan pernyataan penghakiman adalah komponen asas program, tetapi ia selalunya tidak ditemui dalam perpustakaan kod yang sangat baik, kerana jalinan pernyataan ini akan mengaburkan baris utama. logik sistem. Biarkan fikiran kita tersesat dalam pengesanan kod yang meletihkan itu sendiri telah mengurangkan keperluan untuk penyataan gelung melalui fungsi seperti masing-masing dan untuk penyataan penghakiman, ia diproses terutamanya melalui jadual pemetaan. Fungsi val( ) jQuery perlu melakukan pemprosesan yang berbeza untuk teg yang berbeza, jadi tentukan jadual pemetaan fungsi dengan tagName sebagai kunci


Salin kod Kod adalah seperti berikut:valHooks: { option: {get:function(){}}}
Dengan cara ini anda tidak perlu menulis
di mana-mana dalam program

Salin kod Kod adalah seperti berikut:if(elm.tagName == 'OPTION'){
Kembali ...;
}else if(elm.tagName == 'TEXTAREA'){
Kembali ...;
}

Boleh diproses secara bersatu


Salin kod Kod adalah seperti berikut:(valHooks[elm.tagName.toLowerCase()] || defaultHandler) .get( elm);
Jadual pemetaan mengurus fungsi sebagai data biasa dan digunakan secara meluas dalam bahasa dinamik Khususnya, objek itu sendiri adalah bekas untuk fungsi dan pembolehubah dan boleh dianggap sebagai jadual pemetaan Teknik yang digunakan secara meluas dalam jQuery adalah menggunakan pemetaan nama To secara dinamik menjana kod, membentuk mekanisme seperti templat Contohnya, untuk melaksanakan dua fungsi yang sangat serupa myWidth dan myHeight, kita tidak memerlukan
.

Salin kod Kod adalah seperti berikut:jQuery.fn.myWidth = function(){
         return parseInt(this.style.width,10) 10;
}
 
jQuery.fn.myHeight = function(){
Kembalikan parseInt(this.style.height,10) 10;
}

Sebaliknya, anda boleh memilih untuk menjana
secara dinamik

Salin kod Kod adalah seperti berikut:
jQuery.each(['Lebar','Ketinggian'],fungsi(nama){
jQuery.fn['nama saya'] = function(){
           return parseInt(this.style[name.toLowerCase()],10) 10;
}
});


12. Mekanisme pemalam: Sebenarnya saya sangat mudah

Apa yang dipanggil pemalam jQuery sebenarnya adalah fungsi yang ditambahkan pada $.fn Jadi apakah fn ini?

Salin kod Kod adalah seperti berikut:
(fungsi(tetingkap,tidak ditentukan){
// Terdapat pakej lain di dalam
var jQuery = (fungsi() {
var jQuery = fungsi(pemilih, konteks) {
                   kembalikan jQuery.fn.init baharu( pemilih, konteks, rootjQuery );
}
....
// fn sebenarnya adalah singkatan prototaip
jQuery.fn = jQuery.prototype = {
​​​pembina: jQuery,
            init: fungsi (pemilih, konteks, rootjQuery) {... }
}
 
// Memanggil jQuery() adalah bersamaan dengan new init(), dan prototaip init ialah prototaip jQuery
​​jQuery.fn.init.prototype = jQuery.fn;
 
// // Objek jQuery yang dikembalikan di sini hanya mempunyai fungsi paling asas Berikut ialah siri extend
Kembalikan jQuery;
})();
...
//Dedahkan jQuery sebagai objek global
​ window.jQuery = window.$ = jQuery;
})(tetingkap);

Jelas sekali, $.fn sebenarnya adalah singkatan kepada jQuery.prototype

Pemalam tanpa kewarganegaraan hanyalah fungsi, sangat mudah

Salin kod Kod adalah seperti berikut:
// Tentukan pemalam
(fungsi($){
$.fn.hoverClass = fungsi(c) {
           kembalikan this.hover(
                 function() { $(this).toggleClass(c); );
};
})(jQuery);

//Gunakan pemalam
$('li').hoverClass('hover');

Untuk pembangunan pemalam yang lebih kompleks, UI jQuery menyediakan mekanisme kilang widget,


Salin kod Kod adalah seperti berikut:$.widget("ui.dialog", {
Pilihan: {
        autoBuka: benar,...
},
_create: function(){ ... },
_init: function() {
           jika ( this.options.autoOpen ) {
This.open();
}
},
_setOption: fungsi(kunci, nilai){ ... }
          musnahkan: function(){ ... }
});

Apabila memanggil $('#dlg').dialog(options), kod sebenar yang dilaksanakan pada asasnya adalah seperti berikut:


Salin kod Kod adalah seperti berikut:
ini.setiap(fungsi() {
         var instance = $.data( ini, "dialog" );
           jika ( contoh ) {
Instance.option( pilihan || {} )._init();
         } lain {
               $.data( ini, "dialog", $.ui.dialog( pilihan, ini ) );
}
}

Ia boleh dilihat bahawa pada kali pertama fungsi $('#dlg').dialog() dipanggil, contoh objek tetingkap akan dibuat dan disimpan dalam data Pada masa ini, fungsi _create() dan _init() akan dipanggil, dan jika Jika ia tidak dipanggil buat kali pertama, kaedah _init() dipanggil pada tika objek sedia ada Memanggil $('#dlg').dialog() berbilang kali tidak akan mencipta berbilang kejadian.

13. sniffer pelayar lwn. pengesanan ciri

Penghidu penyemak imbas pernah menjadi teknologi yang sangat popular, seperti dalam jQuery awal

Salin kod Kod adalah seperti berikut:
jQuery.browser = {
Versi:(userAgent.match(/. (?:rv|it|ra|ie)[/: ]([d.] )/) || [0,'0'])[1],
​​​ safari:/webkit/.test(userAgent),
​​opera:/opera/.test(userAgent),
          msie:/msie/.test(userAgent) && !/opera/.test(userAgent),
mozilla:/mozilla/.test(userAgent) && !/(compatible|webkit)/.test(userAgent)
};

Dalam kod khusus, pemprosesan berbeza boleh dilakukan untuk penyemak imbas yang berbeza

Salin kod Kod adalah seperti berikut:
if($.browser.msie) {
// buat sesuatu
} else if($.browser.opera) {
// ...
}

Walau bagaimanapun, apabila persaingan dalam pasaran penyemak imbas semakin meningkat, pesaing meniru dan menyamar antara satu sama lain, mengakibatkan kekacauan userAgent Digabungkan dengan kelahiran Chrome dan kebangkitan Safari, IE juga telah mula mempercepatkan langkahnya ke arah standard, dan sniffers. tidak lagi boleh melakukannya. Sebagai kaedah pengesanan yang lebih halus dan khusus, pengesanan ciri secara beransur-ansur menjadi cara utama untuk menangani keserasian penyemak imbas

Salin kod Kod adalah seperti berikut:
jQuery.support = {
// IE mendahului ruang putih apabila .innerHTML digunakan
​​​​leadingWhitespace: ( div.firstChild.nodeType === 3 ),
...
}
Hanya berdasarkan apa yang anda lihat sebenarnya, dan bukannya apa yang pernah anda ketahui, ini memudahkan untuk serasi dengan masa depan.

14. Prototaip lwn. jQuery

prototype.js ialah perpustakaan dengan aspirasi tinggi Matlamatnya adalah untuk memberikan pengalaman pengguna baharu, mengubah JavaScript daripada peringkat bahasa dengan merujuk kepada Ruby, dan akhirnya mengubah wajah js. $. Sebaliknya, jQuery lebih pragmatik dan matlamatnya hanya untuk menulis lebih sedikit dan melakukan lebih banyak lagi

Namun, nasib yang menunggu idealis radikal sering mati sebelum cita-cita mereka dipenuhi Apabila fungsi pengikat ikonik prototaip.js telah diserap ke dalam piawaian ECMAScript, penurunannya telah ditakdirkan objek ialah kemahiran rahsia unik prototype.js, dan ia juga merupakan tumit Achillesnya Terutama apabila ia cuba meniru jQuery dan mengembalikan objek yang dipertingkatkan melalui Element.extend(element), ia dibuang sepenuhnya oleh Prototaip. js berbeza daripada jQuery Ia sentiasa mengubah suai prototaip objek asli Walau bagaimanapun, pelayar adalah medan yang penuh dengan pepijat, pembohongan, bagasi sejarah dan konspirasi komersial. Isu prestasi, konflik nama, isu keserasian, dsb. tidak dapat diselesaikan dengan keupayaan pustaka bantuan Versi 2.0 Prototype.js dikatakan sedang mengalami perubahan besar. Saya tidak tahu sama ada hendak berputus asa keserasian, atau teruskan Berjuang untuk bertahan dalam celah-celah.

Saya harap artikel ini akan membantu pengaturcaraan jQuery semua orang.

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Cadangan popular
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan