Memandangkan logik kod js semakin berat dan berat, fail js mungkin mempunyai beribu-ribu baris, yang sangat tidak sesuai untuk pembangunan dan penyelenggaraan. Baru-baru ini, saya membahagikan JS yang berat logik kepada modul Apabila saya bergelut dengan sama ada untuk menggunakan requirejs atau seajs, akhirnya saya memilih requirejs. Lagipun, dokumen rasmi lebih profesional...
Namun, walaupun dengan dokumentasi rasmi yang lengkap, kami masih menghadapi banyak masalah, seperti penggunaan jquery-ui.
Berikut ialah penjelasan langkah demi langkah tentang masalah yang saya hadapi dan penyelesaiannya.
Pemahaman AMD dan CMD
Contoh biasa AMD (definisi modul tak segerak) ialah requirejs, manakala contoh tipikal CMD (definisi modul biasa) ialah seajs Taobao.
Persamaan mereka ialah kedua-duanya memuatkan js secara tidak segerak. Tetapi perbezaannya ialah require.js akan dilaksanakan serta-merta selepas dimuatkan manakala seajs tidak akan dilaksanakan sehingga ia memasuki fungsi utama dan perlu dilaksanakan.
Jika anda menggunakan seajs, kecekapan pemuatan dan pelaksanaan awal akan lebih tinggi, tetapi js mungkin diambil dan dilaksanakan semasa penggunaan, jadi ketinggalan mungkin berlaku dan menjejaskan pengalaman pengguna (saya belum mencubanya, jadi jika saya salah, Jangan terkejut). Dan requirejs melaksanakan semua js yang dimuatkan pada masa ini, jika terdapat beberapa kaedah pelaksanaan dalam modul anda, ia mungkin tidak dilaksanakan dalam susunan yang anda mahu.
Oleh itu, jika anda biasa dengan pengaturcaraan tak segerak dan ingin mempunyai dokumentasi yang lengkap, disyorkan untuk menggunakan requirejs jika anda ingin mempunyai keperluan khas untuk perintah pelaksanaan dan memudahkan pembangunan, anda juga boleh menggunakan seajs.
Bagaimana untuk menyelesaikan masalah pergantungan bulat dalam requirejs
Jika modul a yang anda takrifkan menggunakan modul b, dan modul b menggunakan modul a, maka pengecualian kebergantungan bulat akan dilemparkan.
Sebagai contoh, saya menulis contoh pergantungan bulat di sini.
Halaman utama:
<!DOCTYPE html> <html> <head> </head> <body> <script data-main="test.js" src="lib/require.js"></script> </body> </html>
Kaedah utama:
requirejs.config({ baseUrl: './' }); requirejs(['js/a'],function (a){ console.log("in test"); a.testfromb(); });
Dalam modul a.js, kaedah test() menyediakan kaedah memanggil b, dan kaedah testfromb() memanggil kaedah b
define(function(require){ var b = require("js/b"); console.log("in a"); return { atest:function(){ console.log("test in a"); }, testfromb:function(){ console.log("testfromb in a"); b.btest(); } } });
Dalam modul b, kaedah a dipanggil.
define(function(require){ var a = require("js/a"); console.log("in b"); return { btest:function(){ console.log("test in b"); a.atest(); } } });
Ini bersamaan dengan kaedah panggilan b, tetapi kaedah b bergantung pada kaedah a, yang mewujudkan kebergantungan bulat. Penyemak imbas akan menggesa ralat:
Uncaught Error: Module name "js/a" has not been loaded yet for context: _
Menurut dokumentasi rasmi, ini adalah masalah reka bentuk dan harus dielakkan sebaik mungkin. Jadi apa yang perlu anda lakukan jika anda tidak dapat mengelakkannya? Modul b boleh diubah suai seperti ini:
define(function(require){ // var a = require("js/a"); console.log("in b"); return { btest:function(){ console.log("test in b"); require("js/a").atest(); } } });
Ini adalah untuk menunggu sehingga kaedah test() dilaksanakan sebelum memuatkan modul. Pada masa ini, modul a jelas telah dimuatkan. Anda boleh melihat maklumat output:
in b a.js:3 in a test.js:6 in test a.js:9 testfromb in a b.js:6 test in b a.js:6 test in a
Dengan cara yang sama, ia mungkin tidak berfungsi jika anda mengubah suai a. Ini kerana susunan pemuatan modul bermula dari b.
Untuk kod sumber kebergantungan bulat, sila rujuk cakera awan
Cara menggunakan jquery dalam requirejs
Jika anda ingin menggunakan jquery dengan agak mudah, cuma tambah kebergantungan yang sepadan terus ke main.js:
requirejs.config({ baseUrl: './', paths:{ 'jquery':'lib/jquery' } }); requirejs(['jquery'], function ($){ $('#test').html('test'); });
Cara menggunakan pemalam jquery dalam requirejs
Untuk pemalam jquery, pendekatan biasa adalah untuk menghantar objek jquery dan menambah kaedah yang sepadan bagi pemalam berdasarkan objek jquery ini.
Mula-mula anda perlu menambah kebergantungan pemalam jquery Berikut ialah dua pemalam sebagai contoh - jquery-ui dan jquery-datatables
requirejs.config({ baseUrl: './', paths:{ 'jquery':'lib/jquery', 'jquery-ui':'lib/jquery-ui', 'jquery-dataTables':'lib/jquery.dataTables' }, shim:{ 'jquery-ui':['jquery'], 'jquery-dataTables':['jquery'] } }); requirejs(['jquery','jquery-ui','jquery-dataTables'], function ($){ .... });
Memandangkan pemalam jquery semua perlu bergantung pada jquery, kebergantungan boleh ditentukan dalam shim.
Selain kaedah penggunaan di atas, anda juga boleh menggunakan panggilan gaya commonJS:
define(function(require){ var $ = require('jquery'); require('jquery-ui'); require('jquery-dataTables'); //下面都是测试,可以忽略 var _test = $('#test'); _test.selectmenu({ width : 180, change : function(event, ui) { console.log('change'); } }); return { test:function(){ //测试jquery-ui _test.append($('<option>test1</option><option>test1</option>')); _test.selectmenu("refresh"); //测试jquery-datatables var _table = $('table'); _table.dataTable(); } } });
Walau bagaimanapun, apabila melaksanakan kod di atas, pengecualian akan dilaporkan:
Uncaught TypeError: _table.dataTable is not a function
Ini kerana dataTables bukan modul gaya memerlukan, jadi jika ia diperkenalkan secara langsung seperti ini, fungsi tanpa nama dalamannya tidak akan dilaksanakan. Anda boleh mengubah suai fungsi tanpa namanya, menghantar objek $, dalam baris terakhir:
*/ return $.fn.dataTable; //}));原来是这样 }($)));//这里增加执行这个匿名函数,并且传入$对象。 }(window, document));
Ini juga kaedah mencari di Internet, tetapi prinsipnya adalah kerana kekurangan pengalaman....
Anda boleh merujuk kepada cakera awan untuk kod sampel Memandangkan sumber yang diimport tidak lengkap, ralat akan dilaporkan dan boleh diabaikan kerana dapat melaksanakan pemalam UI bermakna ia telah berjaya.
Masalah menggunakan jquery-ui dengan requirejs
Memandangkan requirejs akan dilaksanakan serta-merta selepas memuatkan fail js, jika pemalam jquery ui anda perlu memuat semula halaman DOM, ia boleh menyebabkan acara halaman gagal.
Sebagai contoh, selepas modul anda dimuatkan, acara klik terikat pada elemen tertentu $('#test') pada halaman. Walau bagaimanapun, jika pemalam UI tertentu digunakan, pemalam itu akan memaparkan semula elemen DOM dan peristiwa klik yang sepadan dengan ujian akan menjadi tidak sah.
Penyelesaian:
•Tangguhkan pengikatan peristiwa sehingga elemen DOM dipaparkan dan kemudian pencetus pengikatan secara manual;
•Tangkapan peristiwa juga boleh digunakan dan bukannya pengikatan peristiwa elemen DOM (terlalu menyusahkan...tidak disyorkan).
Senario biasa: