jQuery ialah salah satu rangka kerja bahagian hadapan yang paling banyak digunakan, dan sejumlah besar perpustakaan dan pemalam pihak ketiga dibangunkan berdasarkannya. Untuk mengelakkan pencemaran ruang nama global, jQuery menyediakan kaedah jQuery.noConflict() untuk menyelesaikan konflik berubah. Kaedah ini, tanpa ragu, sangat berkesan. Malangnya, dokumentasi rasmi jQuery tidak menerangkan kaedah ini dengan cukup jelas, dan ramai pembangun tidak tahu apa sebenarnya yang berlaku apabila mereka memanggil jQuery.noConflict(), mengakibatkan banyak masalah apabila menggunakannya. Walaupun begitu, prinsip pelaksanaan di sebalik jQuery.noConflict() masih bernilai dipelajari dan dikuasai oleh pembangun web, dan ia boleh menjadi alat yang berkuasa untuk menyelesaikan masalah seperti pencemaran ruang nama global.
Apakah peranan jQuery.noConflict()?
jQuery.noConflict() wujud untuk satu tujuan sahaja: ia membenarkan anda memuatkan berbilang contoh jQuery pada halaman yang sama, terutamanya versi jQuery yang berbeza. Anda mungkin tertanya-tanya, mengapa anda perlu memuatkan/menggunakan pelbagai versi objek jQuery yang berbeza pada satu halaman? Secara umumnya, terdapat dua situasi. Dalam kes pertama, kod perniagaan anda menggunakan versi terkini pustaka jQuery, dan pemalam pihak ketiga yang anda pilih bergantung pada versi pustaka jQuery yang lebih awal, dalam kes kedua, anda mengekalkan sistem yang sudah ada; perniagaan Atas pelbagai sebab, kod tersebut merujuk versi lama perpustakaan jQuery, dan modul anda yang baru dibangunkan menggunakan versi lain pustaka jQuery. Dalam kedua-dua kes, anda perlu menghadapi masalah konflik objek/kaedah jQuery. Nasib baik, jQuery.noConflict() membantu anda menyelesaikan masalah ini.
Apa yang berlaku apabila jQuery dimuatkan?
Apabila jQuery dirujuk/dimuatkan oleh halaman, ia dirangkumkan dalam fungsi laksana sendiri (fungsi tanpa nama Semua pembolehubah, fungsi dan objek yang disediakannya berada dalam persekitaran boleh laku di dalam fungsi tanpa nama dan persekitaran luaran). tidak boleh Dipanggil untuk mengelakkan pencemaran ruang nama global.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
jQuery mentakrifkan dua objek global: jQuery dan $ di dalam fungsi tanpa nama, mendedahkan dirinya kepada persekitaran luaran. Pelbagai kaedah awam yang digunakan oleh pembangun diakses melalui dua objek ini, seperti jQuery.ajax(), jQuery.css(), dsb. Pada mulanya, mereka menunjuk ke objek yang sama jQuery (pembolehubah peribadi) di dalam fungsi tanpa nama, di mana pembolehubah dan fungsi peribadi di dalam fungsi tanpa nama diakses. Ini membolehkan pembolehubah peribadi dalaman dan fungsi fungsi tanpa nama masih berada dalam memori selepas ia dilaksanakan dan tidak akan dikosongkan oleh mekanisme pengumpulan sampah JavaScript.
window.jQuery = window.$ = jQuery;
Apabila jQuery dimuatkan oleh halaman, halaman semasa mungkin sudah mempunyai dua pembolehubah global jQuery dan $ (contohnya, perpustakaan pihak ketiga yang lain dimuatkan, dan ia juga ditakrifkan secara dalaman), yang akan menyebabkan objek Sedia Ada ditimpa (pencemaran ruang nama global). Untuk menyelesaikan masalah ini, jQuery secara dalaman menyimpan pembolehubah global sedia ada dan menyimpannya dalam pembolehubah peribadi _jQuery dan _$ untuk panggilan seterusnya. Oleh itu, jika objek jQuery dan $ belum wujud apabila pustaka jQuery dimuatkan pada halaman, maka _jQuery dan _$ kedua-duanya tidak ditentukan jika tidak, mereka akan menyimpan rujukan kepada jQuery dan $ (mungkin dari pihak ketiga perpustakaan yang dirujuk sebelum ini) Atau versi perpustakaan jQuery yang berbeza). Selepas itu, jQuery akan menimpa dua pembolehubah global ini dan mendedahkan dirinya kepada persekitaran luaran seperti yang diterangkan di atas. Pada ketika ini, pembolehubah global jQuery dan $ pada halaman telah menunjuk kepada perpustakaan jQuery yang baru diperkenalkan.
// Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$, // Otherwise expose jQuery to the global object as usual window.jQuery = window.$ = jQuery;
Kesan ajaib jQuery.noConflict()?
Anggapkan bahawa sistem yang anda uruskan sudah merujuk versi 1.7.0 pustaka jQuery, dan anda merujuk versi 1.10.2 pustaka jQuery dalam fungsi yang baru ditambah. Jadi, adakah cara untuk menggunakan semula jQuery 1.7.0 atau menggunakan kedua-dua versi perpustakaan jQuery pada masa yang sama? Jawapannya ya, iaitu jQuery.noConflict(). Malah, menggunakan jQuery.noConflict(), anda boleh segera mengubah hala pembolehubah global jQuery dan $ ke objek yang dirujuk sebelum ini. Menakjubkan, bukan? Inilah sebabnya mengapa jQuery secara dalaman menyimpan objek yang dirujuk sebelum ini sebelum mendedahkan dirinya kepada dunia luar.
jQuery.noConflict() menerima parameter Boolean pilihan, biasanya nilai lalai adalah palsu. Apakah kesan yang akan diberikan oleh parameter ini? Sebenarnya, ia sangat mudah. Jika jQuery.noConflict() atau jQuery.noConflict(false) dipanggil, hanya pembolehubah global $ akan ditetapkan semula kepada nilai rujukan sebelumnya jika jQuery.noConflict() atau jQuery.noConflict(true) dipanggil, maka pembolehubah global; $ akan ditetapkan semula kepada nilai rujukan sebelumnya, kedua-dua jQuery dan $ akan ditetapkan semula kepada nilai rujukan sebelumnya. Ini sangat penting dan disyorkan untuk diingati. Apabila anda memanggil jQuery.noConflict(false/true), ia akan mengembalikan contoh jQuery semasa Menggunakan ciri ini, kami boleh menamakan semula jQuery.
// "Renaming" jQuery var jayquery = jQuery.noConflict( true ); // Now we can call things like jayquery.ajax(), jayquery.css(), and so on
Mari kita lihat coretan kod lain untuk menguji sama ada kita benar-benar memahami noConflict() yang ajaib
<!-- jQuery and $ are undefined --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <!-- jQuery and $ now point to jQuery 1.10.2 --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"> <!-- jQuery and $ now point to jQuery 1.7.0 --> <script>jQuery.noConflict();</script> <!-- jQuery still points to jQuery 1.7.0; $ now points to jQuery 1.10.2 --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"> <!-- jQuery and $ now point to jQuery 1.6.4 --> <script>var jquery164 = jQuery.noConflict( true );</script> <!-- jQuery now points to jQuery 1.7.0; $ now points to jQuery 1.10.2; jquery164 points to jQuery 1.6.4 -->
避免第三方库的冲突
以上的代码片段展示了如何解决多版本jQuery的冲突。接下来,我们尝试解决jQuery库和第三方库的冲突,下面出现的代码片段在jQuery的官方文档中都有,有兴趣的程序猿可以仔细阅读官方文档体会其中的区别。
直接使用No-Conflict模式
使用No-Conflict模式,其实就是对jQuery进行重命名,再调用。
<!-- 采用no-conflict模式,jquery.js在prototype.js之后被引入. --> <script src="prototype.js"></script> <script src="jquery.js"></script> <script> var $j = jQuery.noConflict(); // $j 引用了jQuery对象本身. $j(document).ready(function() { $j( "div" ).hide(); }); // $ 被重新指向prototype.js里定义的对象 // document.getElementById(). mainDiv below is a DOM element, not a jQuery object. window.onload = function() { var mainDiv = $( "main" ); } </script>
使用自执行函数封装
使用这种方式,你可以在匿名函数内部继续使用标准的$对象,这也是众多jQuery插件采用的方法。需要注意的是,使用这种方法,函数内部无法再使用prototype.js定义的$对象了。
<!-- jquery.js在prototype.js之后被引入. --> <script src="prototype.js"></script> <script src="jquery.js"></script> <script> jQuery.noConflict(); (function( $ ) { // Your jQuery code here, using the $ })( jQuery ); </script>
使用标准jQuery(document).ready()函数
如果jQuery库在其它库之前引入,那么jQuery内部定义的jQuery和$会被第三方库覆盖,这时候再使用noConflict()已经没有什么意义了。解决的方法很简单,直接使用jQuery的标准调用方式。
<!-- jquery.js在prototype.js之前被引入. --> <script src="jquery.js"></script> <script src="prototype.js"></script> <script> // Use full jQuery function name to reference jQuery. jQuery( document ).ready(function() { jQuery( "div" ).hide(); }); // 或者 jQuery(function($){ // Your jQuery code here, using the $ }); // Use the $ variable as defined in prototype.js window.onload = function() { var mainDiv = $( "main" ); }; </script>
下面给大家介绍jQuery noConflict() 方法
noConflict() 方法会释放会 $ 标识符的控制,这样其他脚本就可以使用它了。
实例
当然,您仍然可以通过全名替代简写的方式来使用 jQuery:
$.noConflict(); jQuery(document).ready(function(){ jQuery("button").click(function(){ jQuery("p").text("jQuery 仍在运行!"); }); });
实例
您也可以创建自己的简写。noConflict() 可返回对 jQuery 的引用,您可以把它存入变量,以供稍后使用。请看这个例子:
var jq = $.noConflict(); jq(document).ready(function(){ jq("button").click(function(){ jq("p").text("jQuery 仍在运行!"); }); });
实例
如果你的 jQuery 代码块使用 $ 简写,并且您不愿意改变这个快捷方式,那么您可以把 $ 符号作为变量传递给 ready 方法。这样就可以在函数内使用 $ 符号了 - 而在函数外,依旧不得不使用 "jQuery":
$.noConflict(); jQuery(document).ready(function($){ $("button").click(function(){ $("p").text("jQuery 仍在运行!"); }); });