兼容第三方框架 jQuery多庫共存機(jī)制詳解
在Web項(xiàng)目開發(fā)中,經(jīng)常需要引用第三方JavaScript庫,如果第三方JavaScript庫與自已的JavaScript庫使用相同的全局變量,是一個(gè)比較麻煩的事。程序員多半可能會(huì)修改其中一方的JavaScript代碼。能不能有一個(gè)比較好的方法解決呢?讓我們看一下jQuery如何做到的。
jQuery多庫共存機(jī)制指jQuery庫完全兼容第三方庫,例如jQuery中使用$做為函數(shù)入口,在該頁面同時(shí)引入另一個(gè)庫,其中也使用了$做為函數(shù)名。因此jQuery與該庫發(fā)生沖突,例1:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <HTML>
- <HEAD>
- <TITLE> New Document </TITLE>
- <script src = "http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" language = "javascript"></script>
- <SCRIPT LANGUAGE="JavaScript">
- <!--
- //第三方庫
- function $(str)
- {
- return document.getElementById(str) ;
- }
- function jQuery(str)
- {
- return document.getElementById(str) ;
- }
- //-->
- </SCRIPT>
- </HEAD>
- <BODY>
- <input type = "text" id = "txt1" value = "aa" />
- </BODY>
- </HTML>
在如上示例中 第三方庫同時(shí)使用了"$"與"jQuery",此時(shí)jQuery入口被第三方庫覆蓋了。jQuery提供了noConflict函數(shù)解決沖突,例2:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <HTML>
- <HEAD>
- <TITLE> New Document </TITLE>
- <script src = "http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" language = "javascript"></script>
- <script>
- //兼容代碼
- var $1 = $.noConflict();
- $1(document).ready(function(){
- alert($1("#txt1").val())
- alert($("txt1").value) ;
- })
- </script>
- <SCRIPT LANGUAGE="JavaScript">
- <!--
- //第三方庫
- function $(str)
- {
- return document.getElementById(str) ;
- }
- function jQuery(str)
- {
- return document.getElementById(str) ;
- }
- //-->
- </SCRIPT>
- </HEAD>
- <BODY>
- <input type = "text" id = "txt1" value = "aa" />
- </BODY>
- </HTML>
noConflict重新將jQuery入口指針指向$1,此時(shí)可以用$1訪問jQuery庫,其中兼容代碼要寫在第三方庫載入之前(如果寫在之后,jQuery的$和jQuery入口被第三方庫覆蓋了,無法調(diào)用兼容代碼)。
在實(shí)際應(yīng)用中,如果jQuery載入位置在第三方庫之后,jQuery會(huì)覆蓋第三方JavaScript庫么?如下代碼,例3:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <HTML>
- <HEAD>
- <TITLE> New Document </TITLE>
- <SCRIPT LANGUAGE="JavaScript">
- <!--
- //第三方庫
- function $(str)
- {
- return document.getElementById(str) ;
- }
- function jQuery(str)
- {
- return document.getElementById(str) ;
- }
- //-->
- </SCRIPT>
- <script src = "http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" language = "javascript"></script>
- </HEAD>
- <BODY>
- <input type = "text" id = "txt1" value = "aa" />
- </BODY>
- </HTML>
此處jQuery加載完畢已經(jīng)將第三方庫覆蓋了。如果想調(diào)用第三方庫,似乎有點(diǎn)困難。當(dāng)然jQuery已經(jīng)提供了解決方法,例4:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <HTML>
- <HEAD>
- <TITLE> New Document </TITLE>
- <SCRIPT LANGUAGE="JavaScript">
- <!--
- //第三方庫
- function $(str)
- {
- return document.getElementById(str) ;
- }
- function jQuery(str)
- {
- return document.getElementById(str) ;
- }
- //-->
- </SCRIPT>
- <script src = "http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" language = "javascript"></script>
- <script>
- //兼容代碼
- var $1 = $.noConflict();
- $1(document).ready(function(){
- alert($1("#txt1").val())
- alert($("txt1").value) ;
- })
- </script>
- </HEAD>
- <BODY>
- <input type = "text" id = "txt1" value = "aa" />
- </BODY>
- </HTML>
例4中同樣在jQuery載入之后調(diào)用"兼容代碼",和例2兼容代碼相同,但意義上有差別.在例2中第三方庫覆蓋了jQuery,其中兼容代碼的作用在第三方庫覆蓋jQuery前,jQuery入口指針賦給"$1".在例4中與上相反,由于jquery庫在載入完成時(shí),已經(jīng)將第三方庫覆蓋了,此時(shí)"$"指向jQuery庫,兼容代碼作用是將"$"重新指向第三方庫.同時(shí)充許重新定義jQuery入口.
jQuery兼容機(jī)制實(shí)現(xiàn)原理(示例代碼以jQuery-1.4.3為例):
- //29-32行
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
- // Map over the $ in case of overwrite
- _$ = window.$,
- //394-402行
- noConflict: function( deep ) {
- window.$ = _$;
- if ( deep ) {
- window.jQuery = _jQuery;
- }
- return jQuery;
- },
其中29-32行,jQuery執(zhí)行前,將window.$,window.jQuery值保存到_$和_jQuery中(此時(shí)函數(shù)指針"jQuery","$"可能指向第三方庫,此處為兼容處理做準(zhǔn)備)。
394-402行將jQuery和$重新賦給window.$,window.jQuery,同時(shí)返回jQuery函數(shù)指針. 不難看出調(diào)用noConflict函數(shù)后,被jQuery"占用"的$與"jQuery"又交還給第三方庫了。
【編輯推薦】