jQuery中的ready方法及实现按需加载css,js
一、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;
}


// css按需加载
function loadCss (cssUrl, callback) {
var elem, bl,
isExecuted = false; // 防止在ie9中,callback执行两次 if ( cssUrl == null ) {
return String(cssUrl);
}
elem = document.createElement('link'),
elem.rel = 'stylesheet';
if ( type(callback) === 'function' ) {
bl = true;
} // for ie
function handle() {
if ( elem.readyState === 'loaded' || elem.readyState === 'complete' ) {
if (bl && !isExecuted) {
callback();
isExecuted = true;
}
elem.onreadystatechange = null;
}
}
elem.onreadystatechange = handle; // for 非ie
if (bl && !isExecuted) {
elem.onload = callback;
isExecuted = true;
} elem.href = cssUrl;
document.getElementsByTagName('head')[0].appendChild(elem);
} // js按需加载
function loadScript(scriptUrl, callback) {
var elem, bl,
isExecuted = false; // 防止在ie9中,callback执行两次 if (scriptUrl == null) {
return String(fn);
}
elem = document.createElement('script');
if ( type(callback) === 'function' ) {
bl = true;
} // for ie
function handle(){
var status = elem.readyState;
if (status === 'loaded' || status === 'complete') {
if (bl && !isExecuted) {
callback();
isExecuted = true;
}
elem.onreadystatechange = null;
}
}
elem.onreadystatechange = handle; // for 非ie
if (bl && !isExecuted) {
elem.onload = callback;
isExecuted = true;
} elem.src = scriptUrl;
document.getElementsByTagName('head')[0].appendChild(elem);
}

PS: 在判断link,script元素是否加载完毕,主要依靠load事件;而在ie9以下浏览器中,并没有load事件,ie为它们都添加了一个readystatechange事件,通过判断
元素的readyState状态确定元素是否已经加载完毕;而奇怪的是,在ie9(还可能存在其他浏览器版本)中,元素既有load事件又有readystatechange事件,因此在代码中添加了一个变量isExecuted,如果执行过回调,那么就不再执行,避免回调执行两次。
三、调用方式

loadCss('http://a.tbcdn.cn/apps/tbtx/miiee/css/base.css', function(){
console.log('css加载完毕');
});
loadScript('http://a.tbcdn.cn/apps/tbtx/miiee/js/jQuery.js', function(){
console.log('js加载完毕');
});
ready(function(){
console.log('dom is ready!');
});

jQuery中的ready方法及实现按需加载css,js的更多相关文章
- 模拟jQuery中的ready方法及实现按需加载css,js实例代码
这篇文章介绍了模拟jQuery中的ready方法及实现按需加载css,js实例代码,有需要的朋友可以参考一下 一.ready函数的实现经常用jQuery类库或其他类库中的ready方法,有时候 ...
- 模拟jQuery中的ready方法及实现按需加载css,js
一.ready函数的实现 经常用jQuery类库或其他类库中的ready方法,有时候想想它们到底是怎么实现的,但是看了一下jQuery中的源码,涉及到的模块比较多,(水平有限)代码比较难看懂:自己结合 ...
- webpack中利用require.ensure()实现按需加载
webpack中的require.ensure()可以实现按需加载资源包括js,css等,它会给里面require的文件单独打包,不和主文件打包在一起,webpack会自动配置名字,如0.js,1.j ...
- js实用方法记录-js动态加载css、js脚本文件
js实用方法记录-动态加载css/js 附送一个加载iframe,h5打开app代码 1. 动态加载js文件到head标签并执行回调 方法调用:dynamicLoadJs('http://www.yi ...
- webpack中实现按需加载
webpack中的require.ensure()可以实现按需加载资源包括js,css等,它会给里面require的文件单独打包,不和主文件打包在一起,webpack会自动配置名字,如0.js,1.j ...
- vue中路由按需加载的几种方式
使用vue-cli构建项目后,我们会在Router文件夹下面的index.js里面引入相关的路由组件,如: import Hello from '@/components/Hello' import ...
- Jquery中$(document).ready()与传统JavaScript中的window.onload方法的区别(2016/8/3)
Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 ...
- Jquery中$(document).ready() 和 JavaScript中的window.onload方法 比较
Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的. 1.执行时间 win ...
- 解决关于jquery中$.get()方法总是报“HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy”错的方法
解决关于jquery中$.get()方法总是报“HierarchyRequestError: Node cannot be inserted at the specified point in the ...
随机推荐
- SQL中条件放在on后与where后的区别
SQL中on条件与where条件的区别 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: ...
- 写一个根据id字段查找记录的缓存函数(javascript)
前不久在参加面试的时候遇到了这样一道题,"写一个根据id字段查找记录的缓存函数,如果之前查过,则直接返回之前查找过的对象,而无须重新查找".当时由于时间较短加上时间比较紧张,考虑并 ...
- 一款非常棒的纯CSS3 3D菜单演示及制作教程
原文:一款非常棒的纯CSS3 3D菜单演示及制作教程 这段时间比较忙,很久没在这里分享一些漂亮的HTML5和CSS3资源了,今天起的早,看到一款很不错的CSS3 3D菜单,觉得非常上眼,就将它分享给大 ...
- Effective C++ 18-23
18.接口用于完整的类,使最小. 用户接口类是指程序猿这个类可以访问所获得的接口,典型接口具有在存在唯一功能,好的包装类的数据成员. 这意味着一个完整的接口,包括所有 合理的功能操作.最小指功能和特征 ...
- NEU 1440 The minimum square sum (平方剩余和欧拉准则)
若p=2或p=4*k+1 则p能够表成两平方数的和的形式 (欧拉和费马已证明,而且有求的方法) 所以答案是p 若p=4*k+3 设a^2=n(mod p) (n!=0) 能够证明不存在b,b^2=p ...
- 【Swift】 GET&POST请求 网络缓存的简单处理
GET & POST 的对比 源码:https://github.com/SpongeBob-GitHub/Get-Post.git 1. URL - GET 所有的参数都包含在 URL 中 ...
- Jenkins + robot framework自动发送邮件报告
一.Jenkins安装插件 进入系统管理—插件管理—可选插件下安装以下插件Email-ext plugin.Email-ext Template Plugin. 安装完如下: 二.系统设置 1.设置系 ...
- Android结构分析Android智能指针(两)
笔者:刘蒿羽 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在上一篇文章中,我们分析了Android智能指针中的强指针sp,本文我们来分析弱指 ...
- 加快XCode编译链接速度(200%+)—XCode编译慢液
最近在一个大型项目的开发的时候遇到一个很头疼的问题,由于该项目的代码更,每次建立联系1纪要.浪费时间调试.因此,一些研究如何提高编译链接速度,这里给大家分享. 为了提高编译和链接的是以下三种方式的速度 ...
- 【Leetcode】Remove Duplicates from Sorted List in JAVA
Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...