jQuery庫(noConflict)衝突解決機制

來源:互聯網
上載者:User

許多的JS架構類庫都選擇使用$符號作為函數或變數名,而且在實際的項目開發中,使用範本語言的話有可能"$"符號即為該範本語言的關鍵字。例如Veclocity範本語言,$是關鍵字.與jQuery一起使用可能會存在衝突(頁面中直接寫jq代碼,引入的js檔案不存在該問題)。吐槽下為啥這麼多js庫喜歡用$($ is money?)。

jQuery是使用$符號作為函數或變數名最為典型的一個。在jQuery中,$符號只是window.jQuery對象的一個引用,因此即使$被刪除,jQuery依然能保證整個類庫的完整性。

jQuery的設計充分考慮了多架構之間的引用衝突。我們可以使用jQuery.noConflict方法來輕鬆實現控制權的轉交。

在論述如何解決jQuery衝突之前,我們有必要先對noConflict函數做一個瞭解,解決衝突的方法就藏在裡面。

jQuery.noConflict
jQuery.noConflict([removeAll]);

預設參數情況下:

運行這個函數將變數$的控制權讓渡給第一個實現它的庫。在運行完這個函數之後,就只能使用jQuery變數訪問jQuery對象(函數不帶參數),例如jQuery("div p")。不過需要注意的是該函數必須在你匯入jQuery檔案之後,並且在匯入另一個導致衝突的庫"之前"使用。當然也應該在其他衝突庫被使用之前,除非jQuery是最後一個匯入的。

當參數為true時,執行noConflict則會將$和jQuery對象本省的控制權全部移交給第一個產生他們的庫。

不過具體的移交機制是如何?的呢?查閱源碼即可發現,在jQuery源碼中定義了兩個私人變數_jQuery,_$。具體如下:

容易理解的是,jQuery通過上面兩個私人的變數映射了window環境下的jQuery和$兩個對象,防止了變數被強行覆蓋。一旦noConflict被調用,jquery可以通過_jQuery,_$,jQuery,$四者之間的差異,來決定控制權的移交方式,具體代碼如:

接下來看看參數設定問題,如果deep沒有設定,_$覆蓋了window.$,此時jQuery的別名$失效了,但是jQuery變數未失效,仍可使用。此時如果有其他庫或代碼重新定義了$變數的話,其控制權就轉交出去了。反之deep設定為true時,_jQuery進一步覆蓋window.jQuery,此時$和jQuery都將失效。

這種操作的好處是,不管是架構混用還是jQuery多版本共存這種高度衝突的執行環境,由於noConflict的控制權移交機制,以及本身返回違背覆蓋的私人變數jQuery對象,完全能夠通過變數映射的方式解決衝突。

樣本

瞭解了jQuery內部解決衝突的實現方式,接下來看看一些實際的情況吧。

1、將$引用的對象映射回原始的對象。

jQuery.noConflict();// 使用 jQueryjQuery("div p").hide();// 使用其他庫的 $()$("content").style.display = 'none';

2、恢複使用別名$,然後建立並執行一個函數,在這個函數的範圍中仍然將$作為jQuery的別名來使用。在這個函數中,原來的$對象是無效的。這個函數對於大多數不依賴於其他庫的外掛程式都十分有效。

jQuery.noConflict();(function($) {   $(function() {    // 使用 $ 作為 jQuery 別名的代碼  });})(jQuery);// 其他用 $ 作為別名的庫的代碼

3、建立一個新的別名用來在接下來的庫中使用jQuery對象。

var j = jQuery.noConflict();// 基於 jQuery 的代碼j("div p").hide();// 基於其他庫的 $() 代碼$("content").style.display = 'none';

基於這種方式,所有的jQuery代碼都通過j進行調用,避免了衝突的可能。

4、完全將jQuery移到一個新的命名空間。

var dom = {};dom.query = jQuery.noConflict(true);        結果:// 新 jQuery 的代碼dom.query("div p").hide();// 另一個庫 $() 的代碼$("content").style.display = 'none';// 另一個版本 jQuery 的代碼jQuery("div > p").hide();

解決衝突方式

衝突的方式無非3中情況:

1、其他庫先於jQuery引用($被佔用).

最簡單的我們可以在任何地方調用jQuery.noConflict函數,之後使用jQuery()座位jQuery對象的製造工廠。

 jQuery.noConflict();       //將變數$的控制權移交給先匯入的庫 jQuery(function(){ jQuery("p").click(function(){   //使用jQuery變數   }); }); $("pp").style.display='none';   //其他庫的調用

此外,如果你想確保jQuery不會與其他庫衝突,但又想使用一個類似"$"的捷徑,可以使用如下代碼:

var $mj=jQuery.noConflict();       //自訂快捷變數 $mj(function(){ $mj("p").click(function(){   //使用jQuery變數   }); }); $("pp").style.display='none';   //其他庫的調用

如果你不想給jQuery自訂名稱,卻想使用$,有不與其他庫衝突.可以有兩種解決方式:

其一:

jQuery.noConflict();        jQuery(function($){   $("p").click(function(){   //在函數內部繼續使用$    }); }); $("pp").style.display='none';   //其他庫的調用

其二:

jQuery.noConflict();       //將變數$控制權讓渡(function($){               //定義匿名函數形參為$$(function(){      //匿名函數內部均為jQuery的$           $("p").click(function(){                      });        });})(jQuery);                //執行匿名函數且傳遞實參jQuery $("pp").style.display='none';   //其他庫的調用

這是較為理想的方式,因為可以改變最少的代碼來實現全面的相容性 2、其他庫後於jQuery被引用

你可以參考上述做一些衝突解決的方法,其實其根本就不衝突,你可以使用jQuery變數做一些jQuery的處理工作。同時可以使用$()方法作為其他庫的捷徑。

3、不同版本jQuery、且有其他庫

可以參考上述樣本,將jQuery完全移到另一個命名空間。

var dom = {};dom.query = jQuery.noConflict(true);// 新 jQuery 的代碼dom.query("div p").hide();// 另一個庫 $() 的代碼$("content").style.display = 'none';// 另一個版本 jQuery 的代碼jQuery("div > p").hide();

最後

jQuery解決衝突的機制是十分靈活的,有了這些衝突解決方案,就可以在項目中安心的使用jQuery了。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.