?
在web项目开发中,经常需要引用第三方js库,如果第三方js库与自已的一个js库使用相同的全局变量,是一个比较麻烦的事.程序员多半可能会修改其中一方的js代码.能不能有一个比较好的方法解决呢?让我们看一下jquery如何做到的.
? jquery 多库共存机制指 jquery 库完全兼容第三方库, 例如jquery中使用 $ 做为函数入口,在该页面同时引入另一个库,其中也使用了 $ 做为函数名。因此jQuery与该库发生冲突
? 例1:
< 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 >
?
在如上示例中 第三方库同时使用了"$"与"jQuery",此时jquery入口被第三方库覆盖了. jquery 提供了noConflict函数解决冲突.
例2:
< 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,此时可以用$1访问jquery库,其中兼容代码要写在第三方库载入之前(如果写在之后,jquery 的 $和jQuery 入口被第三方库覆盖了,无法调用兼容代码).
在实际应用中,如果jquery载入位置在第三方库之后,jquery会覆盖第三方js库么? 如下代码.
例3:
< 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 加载完毕已经将第三方库覆盖了.如果想调用第三方库,似乎有点困难. 当然jquery 已经提供了解决方法
例4:
< 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载入之后调用"兼容代码",和例2兼容代码相同,但意义上有差别.在例2中第三方库覆盖了jquery,其中兼容代码 的作用在第三方库覆盖jquery前,jquery 入口指针赋给"$1".在例4中与上相反,由于jquery库在载入完成时,已经将第三方库覆盖了,此时"$"指向jquery库,兼容代码作用是 将"$"重新指向第三方库.同时充许重新定义jquery入口.
jquery 兼容机制实现原理:
(示例代码以jquery-1.4.3为例 )
?//?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执行前,将window.$,window.jQuery值保存到_$和_jQuery中(此时函数指针"jQuery","$"可能指向第三方库,此处为兼容处理做准备).
? 394-402 行将_jQuery和_$重新赋给window.$,window.jQuery,同时返回jquery函数指针.? 不难看出调用noConflict函数后,被jquery"占用"的$与"jQuery"又交还给第三方库了.