My module Loading System V8

Source: Internet
Author: User

The module loading system is part of the core modules of our framework and is fully integrated with domready. Of course, the core module also provides other common methods, such as several groups, type determination, simple event binding... the current version has the following improvements:

    1. Transfers most of define to require for processing. Define only processes parameters.
    2. Improve the Status and checks of the internal two objects that process dependencies to the lightweight Dom ["@ modules"] and names.
    3. Improve the resolvecallbacks logic to determine whether all dependencies of a module have been loaded successfully to make it more efficient.
    4. Enhanced domready parameter passing determination, originally using a simple typeof expr = "function", but in Safari, typeof nodelist is "function", so use Dom instead. type (expr, "function") determination.

Tested Browser: IE6-9 ff3.6.12 ff5.1 opera11.50 safari 5 chrome14.0.8

// ================================================ ===// Module loading module (Core Module) 2011.8.7 by situ zhengmei // ====================================== ======= (function (global, doc) {VaR _ dom = Global. dom, W3C = Doc. dispatchevent, // W3C event model namespace = Doc. URL. replace (/(#. + | \ W)/g, ''), head = Doc. head | Doc. getelementsbytagname ("head") [0], class2type = {"[object htmldocument]": "document", "[object htmlcollection]": "nodelist", "[Object Staticnodelist] ":" nodelist "," [object ixmldomnodelist] ":" nodelist "," [object domwindow] ":" window "," null ":" null ", "Nan": "Nan", "undefined": "undefined"}, tostring = class2type. tostring;/*** mix, add more members to an object * @ Param {object} target object * @ Param {object} source attribute package * @ Param {Boolean | undefined} override * @ return {object} target object */function mix (target, source, override) {var key, ride = (Override = void 0) | override; For (key in source) {If (ride |! (Key in target) {target [Key] = source [Key] ;}} return target ;}/ *** @ Class Dom * Dom framework has two namespaces, * The first is escape (Doc. URL. split ("#") [0]), dynamically generated based on the page address * The second is Dom, we can use the alias mechanism to override it * @ namespace Dom */var dom = function (expr, context) {If (Dom. type (expr, "function") {// note that in Safari, the typeof nodelist type is function, so Dom must be used. type Dom. ready (expr, true);} else {If (! Dom. FN) throw "must load the 'node' module! "Return new Dom. FN. init (expr, context) ;}} mix (DOM, {UUID: 1, HTML: doc.doc umentelement, head: Head, rword:/[^,] +/g, rreadystate: /loaded | complete | undefined/I, "@ name": "dom", "@ debug": True, "@ emitter": W3C? "Addeventlistener": "attachevent",/*** alias mechanism (equivalent to jquery's noconflict) * @ Param {string} Name new namespace */exports: function (name) {_ DOM & (Global. DOM = _ DOM); name = Name | Dom ["@ name"]; DOM ["@ name"] = Name; global [name] = global [namespace] = This ;}, /*** array ** @ Param {arraylike} nodes the array object of the class to be processed * @ Param {number} start (optional. The starting subscript of the part to be extracted. If it is a negative number, * @ Param {number} end is optional. Specifies where to end the selection * @ return {array} */slice: function (nodes, start, end) {for (VAR I = 0, n = nodes. length, result = []; I <n; I ++) {result [I] = nodes [I];} If (arguments. length> 1) {return result. slice (START, (end | result. length);} else {return result ;},/*** curry * @ Param {Any} A * @ return {function} new function */K: function (a) {return function () {return a ;}},/*** is used to obtain the data type or determine the data type * @ Pa What Ram {Any} OBJ wants to detect * @ Param {string} STR the type to be compared * @ return {string | Boolean} */type: function (OBJ, STR) {var result = class2type [(OBJ = NULL | OBJ! = OBJ )? String (OBJ): tostring. call (OBJ)] | obj. nodename | "#"; if (result. charat (0) = "#") {// compatible with legacy browsers and handle certain situations, such as Windows. opera if (obj. window = OBJ) {result = 'window'; // returns the constructor name} else if (obj. nodetype = 9) {result = 'document'; // returns the constructor name} else if (obj. callee) {result = 'arguments '; // returns the constructor name} else if (isfinite (obj. length) & obj. ITEM) {result = 'nodelist'; // processing node set} else if (obj. open & obj. send) {result = "XMLHttpRequest";} else {result = tostring. call (OBJ ). slice (8,-1) ;}}if (STR) {return STR === result;} return result ;},/*** for debugging, if IE6 is printed directly to the page * @ Param {string} s the content to be printed * @ Param {Boolean} force the print to the page */log: function (s, force) {If (Force |! Global. console) {var DIV = Doc. body & Doc. createelement ("Div"); If (DIV) {Div. innerhtml = s; Doc. body. appendchild (DIV)} else {Global. console. log (s) ;},/*** generates an object with the same key value for High-Speed Determination * @ Param {array | string} if the array is a string, use ", "or separate spaces * @ Param {number} Val (Optional). The default value is 1 * @ return {object} */oneobject: function (array, Val) {If (typeof array = "string") {array = array. match (Dom. rword) | [];} var result = {}, V Alue = Val! = Void 0? VAL: 1; for (VAR I = 0, n = array. length; I <n; I ++) {result [array [I] = value ;}return result ;}); "Boolean, number, String, function, array, date, Regexp, window, document, arguments, nodelist, XMLHttpRequest ". replace (Dom. rword, function (name) {class2type ["[object" + name + "]"] = Name;}); var rmodule =/([^ (\ s] +) \(? ([^)] *) \)? /, Method = W3C? "OnLoad": "onreadystatechange", stack = [], // place the negative callback names = [] // list of module names to be processed var map = Dom ["@ modules"] = {"@ ready ":{}}; /*** script onerror * @ Param {string} Name Module name * @ Param {string} URL module path * @ Param {element} node used to simulate opera to load this module temporarily generated Script node */function fixoperaerror (name, URL, node) {var IFRAME = Doc. createelement ("iframe"); var code = '<SCRIPT> window [document. URL. replace (/(#. + | \ W) /G, "")] = {define: function () {}}< \/SCRIPT> '+' <SCRIPT src = "'+ URL +'" onLoad = "this. ownerdocument. X = 1; "> <\/SCRIPT> '; IFRAME. style. display = "NONE"; head. appendchild (IFRAME); var d = IFRAME. contentdocument; D. write (CODE); D. close (); IFRAME. onload = function () {If (D. X = void 0) {removescript (name, node, true);} IFRAME. onload = NULL; // opera cannot be removed when IFRAME is bound to an event. removechild (this) ;};}/*** loads the module A Script node * @ Param {string} Name Module name * @ Param {string} URL module path */function appendscript (name, URL) {var node = Doc. createelement ("script"); url = URL | Dom. basepath + "/" + name. slice (1) + ". JS "+ (DOM [" debug "]? "? Timestamp = "+ new date:" "); node. charset = "UTF-8"; node. async = true; node. onerror = function () {removescript (name, this, true);} node [Method] = function () {If (Dom. rreadystate. test (this. readystate) {resolvecallbacks (); removescript (name, this) ;}} node. src = URL; Global. opera & fixoperaerror (name, URL, node); head. insertbefore (node, head. firstchild);}/*** remove the temporarily generated Script node * @ Param {string} Name Module name * @ Param {element} node: loading the Script node temporarily generated by this module * @ Param {Boolean} error: loading failed */function removescript (name, node, error) {var parent = node. parentnode; If (parent & parent. nodetype = 1) {If (error |! Map [name]. state) {Dom. stack ('dom. log ("fail to load module ['+ name +']") '); Dom. stack (true); // print the error stack} If (node. clearattributes) {node. clearattributes ();} else {node [Method] = node. onerror = NULL;} parent. removechild (node) ;}}// execute and remove all modules or callback functions of all dependencies resolvecallbacks () {loop: For (VAR I = names. length, repeat, name; name = Names [-- I];) {var OBJ = map [name], deps = obj. deps; For (var key In deps) {If (deps. hasownproperty (key) & map [Key]. State! = 2) {continue loop; }}// if deps is an empty object or the status of the dependent module is 3 if (obj. State! = 2) {names. splice (I, 1); // it must be removed before execution. This prevents the page from being refreshed manually after the DOM tree is created in IE, and the final callback function OBJ will be executed multiple times. callback (); obj. state = 2; repeat = true ;}} repeat & resolvecallbacks ();} mix (DOM, {mix: mix, // bind event (simplified version) bind: W3C? Function (El, type, FN, phase) {el. addeventlistener (type, FN, phase);}: function (El, type, FN) {el. attachevent ("On" + type, function () {fn. call (El, event) ;}) ;}, Stack: function (FN) {If (fn = true) {While (fn = stack. pop () {fn () ;}} else if (typeof FN === "string") {stack. push (new function (FN);} else if (typeof fn = "function") {stack. push (FN) ;},/*** <a href = "http://www.cnblogs.com/rubylouvre/ Archive/2011/02/10/1950940 .html "> path of the core module </A> * @ property * @ Type string */basepath :( function (URL, scripts, node) {scripts = Doc. getelementsbytagname ("script"); node = scripts [scripts. length-1]; url = node. hasattribute? Node. SRC: node. getattribute ('src', 4); Return URL. substr (0, URL. lastindexof ('/');}) (),/*** request module * @ Param {string | array} deps dependency list. If it is a string, separate it with commas, to specify a specific path, write * @ Param {function} module forward callback * @ Param {function} errback negative callback * // Dom. require ("class", "Lang", function () {}) require: function (deps, callback, errback) {VaR _ deps = {}; (deps + ""). replace (Dom. rword, function (URL, name, match) {match = Ur L. Match (rmodule); name = "@" + match [1]; // obtain the module name if (! Map [name]) {// prevents repeated node generation and request map [name] ={}; // state: undefined, not loaded; 1 loaded; 2: executed appendscript (name, Match [2]); // loads the Javascript file Dom. stack (errback); // press into the error stack} _ deps [name] = "situ zhengmei"; // useful is only its key name, content casually }); vaR name = callback. _ name | "@ CB" + (+ new date + math. random (); map [name] = {// create or update the module status callback: callback, deps: _ deps, state: 1}; names. push (name) ;},/*** definition module * @ Param {string} Name Module name * @ Param {string} Dependlist dependency list * @ Param {function} module itself */define: function (name, deps, callback) {If (typeof deps = "function ") {// callback = deps; deps = "";} callback. _ name = "@" + name; // Module name this. require (deps, callback );}}); /*** domready Mechanism * @ Param {function} FN callback function * @ Param {Boolean} More: whether to load the specified module */var ready = Dom. ready = function (FN) {If (ready. list) {ready. list. push (FN);} else {f N () ;}}; ready. list = []; function fireready () {If (ready. list) {for (VAR I = 0, FN; fn = ready. list [I ++];) FN (); Delete ready. list; Map ["@ ready"]. state = 2; resolvecallbacks (); // fix opera does not execute the final callback}; function doscrollcheck () {try {Dom. HTML. doscroll ("Left"); fireready () ;}catch (e) {setTimeout (doscrollcheck, 0) ;}; // starts determining page loading if (Doc. readystate = "complete") {fireready ();} else {Dom. B Ind (Doc, (W3C? "Domcontentloaded": "readystatechange"), function () {If (W3C | Doc. readystate = "complete") {fireready () ;}}); try {// http://bugs.jquery.com/ticket/4787 // under IE6 if the embedded page is reset to document. domain, access window. frameelement throws an error. // The value var toplevel = Global can be accessed only after multiple try catch attempts. frameelement = NULL;} catch (e) {}; if (Dom. HTML. doscroll & toplevel) {doscrollcheck () ;}} dom.exports({{{}(this,this.doc ument);/** 2011.7.11 @ starts with private system variables to prevent direct calls to Dom. check to Dom ["@ emitter"] Dom. change namespace to Dom ["@ name"] To Remove useless Dom. modules optimizes the exports method 2011.8.4 to enhance Dom. log, so that IE6 can also print the log reconstruction fixoperaerror and resolvecallbacks will merge the provide method into require to refactor define, require, add the "@ modules" attribute to the DOM namespace in resolve to enhance the determination of domready parameter passing */
<! Doctype HTML>  

We can use firebug to view the JS Request status. Except for the first request, all other requests are sent using a temporarily generated Script node.

We can view the execution status of each module and find that the order of the request is different. This is because each module is executed only after the module on which it depends is executed.

Let's take a look at the DOM ["@ modules"] structure. The dependency and status of each module can be found here.

For more detailed usage, see V7 introduction.

The following is the function statistics of the modules loaded by my module:

Function Properties involving functions and auxiliary methods Number of rows (including comments)
Type Recognition Mechanism Type 43
Module Loading Mechanism Basepath, require, define
Fixoperaerror, appendscript, removescript, resolvecallbacks
150
Alias Mechanism Exports 10
Mixin Mechanism Mix 16
Domready Mechanism Ready 49
Debugging Mechanism Stack, log, Dom ["@ debug"] 30
Array and cutting Slice 17
High-speed judgment Oneobject 16
Bind event Bind 8

Related links:

My module Loading System V7

my module Loading System V6

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.