jQuery多庫共存問題解決方法


一、問題概述:

1、隨着jQuery的流行,采用jQuery和$符為命名空間的js庫越來越多,當然jQuery的$符也是參照的Prototype庫的,所以當多個庫同時以$符或者jQuery為命名空間時,那么此時,就會產生沖突。

2、由於jQuery的更新速度過快,所以插件更不上,導致不同版本的jQuery對插件支持的不一樣,而剛好我們此時需要用一個高版本的jQuery進行開發,我們用的z-tree則是低版本的jQuery,所以在這種場景下,則會產生$和jQuery命名空間沖突的問題

3、這里jQuery解決多庫共存的問題的絕決方案只用於單文件js類庫框架,如果是多文件就不行了像EXT這種

 

二、解決方法

1、通過jQuery自帶的noConflict函數將$或者jQuery映射回給之前使用過$和jQuery對象的js類庫

簡介:jQuery.noConflict()的具體實現

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
   jQuery={};//模擬jQuery對象
   
   //將$和jQuery兩個對象(命名空間)存入到臨時變量中去,應為這兩個變量可能會和其他庫的變量沖突
   var _$=window.$,_jQuery=window.jQuery;
   //上面定義的_$和_jQuery的變量值可能會存在三種情況
   //第一種當jQuery文件位於最頂端時,那么里面存儲的就是js全局變量的默認值
   //第二種當jQuery文件位於其他js文件之下,且前面的庫庫有使用到window.$和window.jQuery中的任意一個,
//那么當調用下面的noConflict方法之后,jQuery就會將對應的window.$和window.jQuery控制權返還給之前使用到他們的js庫
//實際交還$對象和jQuery對象的方法 jQuery.noConflict=function(deep){ //交還$對象的控制權 //因為jQuery會做window.$=window.jQuery=jQuery這個操作, //將window.$和window.jQuery對象都托管給jQuery對象,所以當 //加載完jQuery文件之后,執行jQuery.noConflict()如果window.$ //對象已經脫管給了jQuery對象的話,那么就通過將原來的 //window.$的值覆蓋現在window.$的形式,完成$對象控制權的交 //換, 所以覆蓋之后的$對象的值就是在jQuery之前使用到$對象的js //庫中定義的值,而我們也不能使用$符來使用選擇器,只能通過jQuery對象 if(window.$===jQuery) { window.$=_$;//將原先緩存的window.$(之前加載完成的js庫的$對象)覆蓋在執行jQuery文件之后重新定義的jQuery自帶的$對象 } //交換jQuery對象的控制權 //jQuery對象不能輕易的交還控制權,所以這里加了一個deep參數,只有當這個參數為true時,才會交還 if(deep && window.jQuery===jQuery) { window.jQuery=_jQuery;//將原先緩存的window.jQuery(之前加載完成的js庫的jQuery對象)覆蓋在執行jQuery文件之后重新定義的jQuery自帶的jQuery對象 }
return jQuery;//返回jQuery對象,這樣的話我們就可以給jQuery對象重新定義一個個性化的名字 }
</script> </body> </html>

(1)通過jQuery.noConflict()交還$和jQuery對象的控制權,解決命名控件沖突的問題

當jQuery文件第一個加載時,調用jQuery.noConflict()交換$的控制權

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../common/jquery-1.9.1.min.js"></script>

</head>
<body>
<script>
    console.log(window.$);//打印function (e,t){return new b.fn.init(e,t,r)} jQuery中定義的$對象
    jQuery.noConflict();
    console.log(window.$);//打印出undefined
</script>
</body>
</html>

 

當jQuery文件在其他js庫加載完之后加載,且這些庫已經使用了$對象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../common/prototype.js"></script>
    <script src="../common/jquery-1.9.1.min.js"></script>

</head>
<body>
<script>
    console.log(window.$);//打印出:function (e,t){return new b.fn.init(e,t,r)} jQuery中定義的$對象
    jQuery.noConflict();
    console.log(window.$);//打印出prototype中定義的$對象
</script>
</body>
</html>

 

(2)通過jQuery.noConflict()來給jQuery對象重新命名的方式解決沖突問題

這實際上也是交換$對象給前面的js類庫后,通過返回的jQuery對象自定義的給jQuery對象命名的方式,解決的方式其實和上面的是一樣的,但是區別是我們可以定義一個個性化的名字(前提是不要和前面的對象沖突)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../common/jquery-1.9.1.min.js"></script>
</head>
<body>
<script>
    var zc=jQuery.noConflict();
    alert(zc("body").length);//輸出:1
</script>
</body>
</html>

 

(3)聽過jQuery.noConflict()方法返還$對象的控制權,通過匿名執行函數(閉包)的方式重新恢復對$對象的使用,只不過,$對象只在閉包范圍內有效

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../common/jquery-1.9.1.min.js"></script>
</head>
<body>
<script>
    jQuery.noConflict();//交還$對象的控制權給前面使用過$對象的js庫
    (function($){
        alert($("body").length);//輸出:1;
    })(jQuery)//將jQuery對象作為實參傳遞給形參$,這樣$還是代表jQuery對象
</script>
</body>
</html>

 

(4)通過jQuery.noConflict()同時去除$對象和jQuery對象的控制權

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../common/jquery-1.9.1.min.js"></script>
</head>
<body>
<script>
    jQuery.noConflict(true);
    alert($);//輸出:undefined
    alert(jQuery);//輸出:undefined
</script>
</body>
</html>

 

 

(5)下面是終極的解決方案,使用這個方案你可以把jQuery集成到你自己定義的js類庫中區,同時,去除$和jQuery對象的控制,也就是說,$和jQuery不再適用,而把jQuery對象的所有的屬性和方法,都轉移到你的對象下面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../common/jquery-1.9.1.min.js"></script>
</head>
<body>
<script>
    var zc={};//自定義的對象
    zc.query=jQuery.noConflict(true);
    alert(zc.query("body").length);//輸出:1
    alert(jQuery);//輸出:undefined
    alert($);//輸出:undefined
</script>
</body>
</html>

通過上面的輸出發現:此時$和jQuery對象均無法使用,而自定義的zc.query怎可以使用jQuery對象所有的屬性和方法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM