调用$.noConflict()放弃对window.$的使用权;
调用$.noConflict(true)放弃对window.jQuery的使用权。
下列是jQuery中的部分源码:
定义三个局部变量:
var _jQuery = window.jQuery,
_$ = window.$,
jQuery = function( selector, context ) {};
相当于var _jQuery = window.jQuery;
var _$ = window.$;
var jQuery = function( selector, context ) {};
// 定义三个局部变量_jQuery,_$,jQuery
var _jQuery = window.jQuery,
_$ = window.$,
jQuery = function( selector, context ) {};
//工具方法:
noConflict: function( deep ) {
if ( window.$ === jQuery ) {
window.$ = _$;
}
if ( deep && window.jQuery === jQuery ) {
window.jQuery = _jQuery;
}
return jQuery;
}
//把局部变量jQuery赋值给两个全局变量
window.jQuery = window.$ = jQuery;
jQuery是局部变量,外界无法访问,window.jQuery = jQuery,就可以访问jQuery了。window.jQuery可以修改,但是jQuery是无法修改的 ,保持不变的,因为jQuery位于立即执行函数内部,外界无法访问,私有变量jQuery始终不变。noConflict()始终会返回私有变量jQuery。window.jQuery和window.$都可以修改。
两个if语句是针对jQuery文件在后面的情况:因为jQuery文件会执行window.jQuery=window.$=jQuery;当jQuery文件在后面时始终满足window.jQuery===window.$===jQuery,最终返回私有变量jQuery(构造函数)
当jQuery文件在前面,后面js文件使用了$,如果想使用jQuery库,直接使用jQuery就可以,jQuery('#id'),不能使用$('#id')。或者var jq = jQuery.noConflict();这样就可以使用jq('#id')代替jQuery('#id'),
当$=123位于<script src="jquery-2.0.3.js"></script>之后:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="jquery-2.0.3.js"></script>//window.$ === window.jQuery === jQuery
<script>
jq=$.noConflict();//window.$ = _$ = undefied
$=123;
jq(function(){
alert($);//123
})
</script>
</head>
<body>
</body>
</html>
当$=123位于<script src="jquery-2.0.3.js"></script>之前:
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script>
$=123;
</script>
<script src="jquery-2.0.3.js"></script>//window.$ === window.jQuery === jQuery
<script>
jq=$.noConflict();//window.$ = _$ = 123
jq(function(){
alert($);//123
})
</script>
</head>
<body>
</body>
</html>
其实源码中的两个if语句主要是针对
$=123位于
<script src="jquery-2.0.3.js"></script>之前的情况,
当有参数deep为true时,jQuery放弃全局变量window.jQuery的使用权
DOM加载事件:
$(function(){})//就是执行$(document).ready(function(){});
.ready()
ready: function( fn ) {
jQuery.ready.promise().done( fn );
return this;
},
jQuery.ready.promise():
jQuery.ready.promise = function( obj ) {
if ( !readyList ) {
readyList = jQuery.Deferred();
//如果此时DOM已经加载完毕,直接执行jQuery.ready()
if ( document.readyState === "complete" ) {
setTimeout( jQuery.ready );
} else {
//如果DOM此时没有加载完,添加监听指令,加载完后执行completed()
document.addEventListener( "DOMContentLoaded", completed, false );
// 针对浏览器的缓存,有缓存时load事件比DOMContentLoaded事件快
window.addEventListener( "load", completed, false );
}
}
return readyList.promise( obj );
};
completed():
completed = function() {
//避免执行两次,第一个触发后,全部取消监听,这样就会只执行一次jQuery.ready();
document.removeEventListener( "DOMContentLoaded", completed, false );
window.removeEventListener( "load", completed, false );
jQuery.ready();
};
$.ready():
ready: function( wait ) {
// 用来处理延时DOM加载
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
return;//只要执行该语句,就不能执行下面的readyList.resolveWith( document, [ jQuery ] );
} //也就不能执行$(function(){})中的函数
// Remember that the DOM is ready
jQuery.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --jQuery.readyWait > 0 ) {
return;
}
//回调函数的执行环境是document,参数是jQuery
//第二个参数是数组形式,这是因为回调函数执行方式是fn.apply(document, [ jQuery ])
//注意call()和apply()的区别,就是参数,call()参数一个一个地写,apply()第二个参数是一个集合
readyList.resolveWith( document, [ jQuery ] );
// $(document).on('ready',function(){});如果是这种情况,可以通过下列方式触发
if ( jQuery.fn.trigger ) {
jQuery( document ).trigger("ready").off("ready");
}
},
因此
$(function(a){
console.log(this);//document
console.log(a);//jQuery
})
如果$被占用了,但还是想使用$符号,可以这样写:
jQuery(function($){
$('#id').show()
})
DOM加载事件有三种写法:
$(function(){});
$(document).ready(function(){});
$(document).on('ready',function(){});
延迟DOM加载:
jQuery.readyWait=1
$.holdReady():
holdReady: function( hold ) {
if ( hold ) {
jQuery.readyWait++;
} else {
jQuery.ready( true );
}
},
window.onload():必须等网页中的所有内容加载完毕(包括图片等),且只能写一个;
$(function(){}):DOM结构加载完毕就可以执行,不用等待图片等其他元素的加载,可以写多个。