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