1. Implementation of the ready function
I often use the ready method in the jQuery class library or other class libraries. Sometimes I think about how they are implemented, but after taking a look The source code in jQuery involves many modules, and the code (with limited level) is difficult to understand; I combined some book contents to summarize.
Let’s first talk about the implementation idea of the ready function:
The variable ready is assigned by an expression. The right side is a self-executing anonymous function. In this anonymous function, first bind the processing function to the event of each browser, and then Assign a value to isReady (determined according to the event asynchronous handler), and then return a parameter-passing closure. In the closure, the isReady value is mainly judged to perform the operation. If the dom structure is ready (isReady === true), the callback is executed. Otherwise, add the callback to the queue (funs) to be executed. When the event handler is executed, loop through the queue (funs) and execute the functions in the queue in sequence. After executing the functions in the queue, you need to clear the queue (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') ) {
length; i ) {
funs[i].call(document);
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:
This function code refers to the authoritative guide book. The only difference is that an additional judgment document.readyState !== 'interactive'
Copy code
The code is as follows:
Interaction and completion status in various browsers The order of appearance is not guaranteed to be consistent. It depends on the browser and the content of the page. If document.readyState !== 'interactive' is added, it means that no matter which stage appears first, the code can be executed earlier. .
2. Load css on demand, js
refers to the jQuery source code and writes a type function to return the parameter type.
Copy code
The code is as follows:
/**
*
* Determine parameter 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: When judging whether the link and script elements have been loaded, we mainly rely on the load event; in browsers below IE9, there is no load event. IE adds a readystatechange event for them all, by judging the
element. The readyState state determines whether the element has been loaded; and strangely, in ie9 (and possibly other browser versions), the element has both a load event and a readystatechange event, so a variable isExecuted is added to the code. If it is executed callback, then it will no longer be executed to avoid executing the callback twice.
3. Calling method
loadCss('http://www.jb51.net/apps/tbtx/miiee/css/base.css', function(){
console.log('css loaded') ;
});
loadScript('http://www.jb51.net/apps/tbtx/miiee/js/jQuery.js', function(){
console.log('js loading Done');
});
ready(function(){
console.log('dom is ready!');
});