許多的JS框架類庫都選擇使用$符號作為函數或變量名,而且在實際的項目開發中,使用模板語言的話有可能"$"符號即為該模板語言的關鍵字。例如Veclocity模板語言,$是關鍵字.與jQuery一起使用可能會存在沖突(頁面中直接寫jq代碼,引入的js文件不存在該問題)。
jQuery是使用$符號作為函數或變量名最為典型的一個。在jQuery中,$符號只是window.jQuery對象的一個引用,因此即使$被刪除,jQuery依然能保證整個類庫的完整性。
jQuery的設計充分考慮了多框架之間的引用沖突。我們可以使用jQuery.noConflict方法來輕松實現控制權的轉交。
在論述如何解決jQuery沖突之前,我們有必要先對noConflict函數做一個了解,解決沖突的方法就藏在里面。
jQuery.noConflict();
1,在省缺參數的情況下,運行這個函數將變量$的控制權讓渡給第一個實現它的庫。在運行完這個函數之后,就只能使用jQuery變量訪問jQuery對象(函數不帶參數),例如jQuery("div p")。
注意該函數的使用時機:
在jQuery導入之后,在其他沖突庫使用之前。
2,當參數為true時,執行noConflict則會將$和jQuery對象本省的控制權全部移交給第一個產生他們的庫。
以下為jQuery2.1.4的部分源碼:
var
// Map over jQuery in case of overwrite
_jQuery = window.jQuery,
// Map over the $ in case of overwrite
_$ = window.$;
jQuery.noConflict = function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
};
容易理解的是,jQuery 通過兩個私有變量映射了 window 環境下的 jQuery 和 $ 兩個對象,以防止變量被強行覆蓋。一旦 noConflict 方法被調用,則通過 _jQuery, _$, jQuery, $ 四者之間的差異,來決定控制權的移交方式。
接下來看看參數設定問題,如果deep沒有設置,_$覆蓋了window.$,此時jQuery的別名$失效了,但是jQuery變量未失效,仍可使用。此時如果有其他庫或代碼重新定義了$變量的話,其控制權就轉交出去了。反之deep設置為true時,_jQuery進一步覆蓋window.jQuery,此時$和jQuery都將失效。
這種操作的好處是,不管是框架混用還是jQuery多版本共存這種高度沖突的執行環境,由於noConflict的控制權移交機制,以及本身返回違背覆蓋的私有變量jQuery對象,完全能夠通過變量映射的方式解決沖突。
例一
將 $ 引用的對象映射回原始的對象:
jQuery.noConflict();
// 使用 jQuery
jQuery(
"div p"
).hide();
// 使用其他庫的 $()
$(
"content"
).style.display =
'none'
;
jQuery.noConflict();
(function($) {
$(function() {
// 使用 $ 作為 jQuery 別名的代碼
});
})(jQuery);
// 其他用 $ 作為別名的庫的代碼
jQuery.noConflict()(function(){ // 使用 jQuery 的代碼 }); ... // 其他庫使用 $ 做別名的代碼
例四
創建一個新的別名用來在接下來的庫中使用jQuery對象。
var j = jQuery.noConflict();
// 基於 jQuery 的代碼
j(
"div p"
).hide();
// 基於其他庫的 $() 代碼
$(
"content"
).style.display =
'none'
;
var dom = {};
dom.query = jQuery.noConflict(
true
);
結果:
// 新 jQuery 的代碼
dom.query(
"div p"
).hide();
// 另一個庫 $() 的代碼
$(
"content"
).style.display =
'none'
;
// 另一個版本 jQuery 的代碼
jQuery(
"div > p"
).hide();