The realization of Ready function
Often use jquery class library or other class library ready method, sometimes think about how they are implemented, but looked at the source of jquery, involved in more modules, (level Limited) code more ugly to understand, the combination of some of the book content, summed up.
Let's talk about the realization of the READY function:
The variable ready is assigned by the expression, and the right-hand side is a self executing anonymous function, in which the event-binding handler function for each browser is first, and the IsReady is assigned a value (based on the event asynchronous handler), and then a reference closure is returned, and in the closed package, The primary judgment is IsReady value to perform the action, if the DOM structure is ready (IsReady = = True), the callback is executed, or the callback is added to the queue to be executed (funs), which loops through the queue (funs) When the event handler executes, and sequentially executes the functions in the queue. After you perform the functions in the queue, you also need to clear the queue (funs = null).
Copy Code code as follows:
var ready = (function () {
var IsReady = False,
Funs = [];
function handle (e) {
if (IsReady) {
Return
}
if (E.type = = ' ReadyStateChange ' && (document.readystate!== ' interactive ' && document.readystate!== ' C Omplete ')) {
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:
The function code is referenced to the authoritative guide books, and the only difference is that there is an additional judgment document.readystate!== ' interactive '
Copy Code code as follows:
if (E.type = = ' ReadyStateChange ' && (document.readystate!== ' interactive ' && document.readystate!== ' C Omplete ')) {
Return
}
The order of interaction and completion status in each browser does not guarantee consistency, depending on the browser and the content of the page, adding this judgment document.readystate!== ' interactive ',
It means that no matter which stage comes first, the code can be executed earlier.
Second, on-demand loading CSS,JS
Referring to the jquery source, wrote a type function that returns the parameter type.
Copy Code code as follows:
/**
*
* Determining parameter types
* 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;
}
Copy Code code as follows:
CSS on-demand loading
function Loadcss (Cssurl, callback) {
var elem, BL,
isexecuted = false; Prevent callback from being executed twice in IE9
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 non IE
if (BL &&!isexecuted) {
Elem.onload = callback;
Isexecuted = true;
}
Elem.href = Cssurl;
document.getElementsByTagName (' head ') [0].appendchild (Elem);
}
JS on-Demand loading
function Loadscript (Scripturl, callback) {
var elem, BL,
isexecuted = false; Prevent callback from being executed twice in IE9
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 non IE
if (BL &&!isexecuted) {
Elem.onload = callback;
Isexecuted = true;
}
ELEM.SRC = Scripturl;
document.getElementsByTagName (' head ') [0].appendchild (Elem);
}
PS: In determining whether the link,script element is loaded, mainly rely on the load event, while in IE9 the following browsers, there is no load event, ie for them to add a ReadyStateChange event, by judging
The readystate state of the element 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 the callback is executed, then no execution is performed and the callback is avoided two times.
Third, the way to call
Copy Code code as follows:
Loadcss (' Http://www.jb51.net/apps/tbtx/miiee/css/base.css ', function () {
Console.log (' CSS loading complete ');
});
Loadscript (' Http://www.jb51.net/apps/tbtx/miiee/js/jQuery.js ', function () {
Console.log (' JS loaded complete ');
});
Ready (function () {
Console.log (' Dom is ready! ');
});