一、ready函数的实现
经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的源码,涉及到的模块比较多,(水平有限)代码比较难看懂;自己结合了一些书籍内容,总结一下。
先说一下ready函数的实现思路:
变量ready通过表达式赋值,右侧为一个自执行匿名函数,在这个匿名函数中,首先为各个浏览器的事件绑定处理函数,并为isReady赋值(根据事件异步处理程序来确定),然后返回一个传参闭包,在闭包中,主要判断isReady值来执行操作,如果dom结构准备就绪(isReady === true),执行回调,否则将回调加入到要执行的队列(funs)中,待事件处理程序执行时,循环遍历队列(funs),并依次执行队列中的函数,执行完队列中的函数后,还需要清除队列(funs = null)。
复制代码 代码如下:
var ready = (function(){
var isReady = false,
funs = [];
function handle (e) {
if ( isReady ) {
return;
}
if ( e.type === 'readystatechange' && (document.readyState !== 'interactive' && document.readyState !== 'complete') ) {
return;
}
for ( var i = 0; i < funs.length; i++ ) {
funs[i].call(document);
}
isReady = true;
funs = null;
}
if ( document.addEventListener ) {
document.addEventListener( 'DOMContentLoaded', handle, false );
document.addEventListener( 'readystatechange', handle, false );
document.addEventListener( 'load', handle, false );
}
else if ( document.attachEvent ) {
document.attachEvent( 'onreadystatechange', handle );
document.attachEvent( 'onload', handle );
}
return function ready (callback) {
if ( isReady ) {
callback.call(document);
}
else {
funs.push(callback);
}
};
}());
PS:
该函数代码参照于权威指南书籍,唯一不同的是,多加了一个判断document.readyState !== 'interactive'
复制代码 代码如下:
if ( e.type === 'readystatechange' && (document.readyState !== 'interactive' && document.readyState !== 'complete') ) {
return;
}
在各个浏览器中交互和完成状态出现顺序并不能保证一致,这取决于浏览器及页面的内容,多加了这个判断document.readyState !== 'interactive'的话,
意思是不管哪个阶段先出现,代码都能更早的执行。
二、按需加载css,js
参照了jQuery源码,写了一个type函数,返回参数类型。
复制代码 代码如下:
/**
*
* 判断参数类型
* createTime: 2013/9/18
*
*/
function type (obj) {
var classTypes, objectTypes;
if ( obj == null ) {
return String(obj);
}
classTypes = {};
objectTypes = ('Boolean Number String Function Array Date RegExp Object Error').split(' ');
for ( var i = 0, len = objectTypes.length; i < len; i++ ) {
classTypes[ '[object ' + objectTypes[i] + ']' ] = objectTypes[i].toLowerCase();
}
if ( typeof obj === 'object' || typeof obj === 'function' ) {
var key = Object.prototype.toString.call(obj);
return classTypes[key];
}
return typeof obj;
}
复制代码 代码如下: