问题
I load js files dynamically in my project putting their content in a script tag in the head. Each file has only an object inside. I noticed that after loading, all objects are in the script tag but only the first is not undefined (the order I put content doesn't change the problem, first is an object, others nope)
This is the script
window.onload = function () {objMaster.end(objMaster.main());};
objMaster = {
// ---------- MAIN
main: function () {
// Setting up the environment
if (!this.set()) return 101;
// Loading core modules
if (!this.load('FrameBee/Core/1_Engineer.js', 'js')) return 201;
if (!this.load('FrameBee/Core/2_Manager.js', 'tmp_js')) return 202;
if (!this.load('FrameBee/Core/3_Lumberjack.js', 'tmp_js')) return 203;
if (!this.load('FrameBee/Core/4_Recruiter.js', 'tmp_js')) return 204;
if (!this.load('FrameBee/Core/5_Sage.js', 'tmp_js')) return 205;
if (!this.load('FrameBee/Core/6_Architect.js', 'tmp_js')) return 206;
if (!this.load('FrameBee/Core/7_Agent.js', 'tmp_js')) return 207;
// Checking core objects declaration
if (typeof objManager !== 'object') return 301;
if (typeof objLumberjack !== 'object') return 302;
if (typeof objRecruiter !== 'object') return 303;
if (typeof objSage !== 'object') return 304;
if (typeof objArchitect !== 'object') return 305;
if (typeof objAgent !== 'object') return 306;
return 1;
},
// ---------- ENDING MAIN
end: function (valIN) {
var strOUT = null;
// Setting up the error message if main() is not true
switch (valIN) {
// Environment
case 101:
strOUT = this.att.error.environment;
break;
// Loading core modules
case 201:
strOUT = 'Engineer' + this.att.error.unreachable;
break;
case 202:
strOUT = 'Manager' + this.att.error.unreachable;
break;
case 203:
strOUT = 'LumberJack' + this.att.error.unreachable;
break;
case 204:
strOUT = 'Recruiter' + this.att.error.unreachable;
break;
case 205:
strOUT = 'Sage' + this.att.error.unreachable;
break;
case 206:
strOUT = 'Architect' + this.att.error.unreachable;
break;
case 207:
strOUT = 'Agent' + this.att.error.unreachable;
break;
// Checking core objects
case 301:
strOUT = 'Manager' + this.att.error.undeclared;
break;
case 302:
strOUT = 'Lumberjack' + this.att.error.undeclared;
break;
case 303:
strOUT = 'Recruiter' + this.att.error.undeclared;
break;
case 304:
strOUT = 'Sage' + this.att.error.undeclared;
break;
case 305:
strOUT = 'Architect' + this.att.error.undeclared;
break;
case 306:
strOUT = 'Agent' + this.att.error.undeclared;
break;
}
// Showing error message only if main() is not true
if (strOUT !== null) document.body.innerHTML =
this.att.error.open +
strOUT +
this.att.error.close;
return 1;
},
// ---------- ATTRIBUTES
att: {
// Class identifier for removing temporary elements in the end
tmp_class: 'FrameBee_Temp',
// IDs of FrameBee head tag environment
id: {
style: 'FrameBee_Head_Style',
tmp_style: 'FrameBee_Head_Style_Temp',
script: 'FrameBee_Head_Script',
tmp_script: 'FrameBee_Head_Script_Temp',
},
// Error messages
error: {
// Enclousers
open: '<h1>FrameBee ERROR</h1><p>:: ',
close: '</p><hr><i>Application is halted</i>',
// Suffix
environment: 'Environment is not properly setted',
unreachable: ' core module is not reachable',
undeclared: ' object is not declared',
},
},
// ---------- METHODS
// .......... Set the HTML environment
set: function () {
var elmTMP = null;
// Adding style element
elmTMP = document.createElement('style');
elmTMP.setAttribute('id', this.att.id.style);
elmTMP.setAttribute('type', 'text/css');
elmTMP.setAttribute('rel', 'stylesheet');
document.head.appendChild(elmTMP);
// Adding temp style element
elmTMP = document.createElement('style');
elmTMP.setAttribute('id', this.att.id.tmp_style);
elmTMP.setAttribute('class', this.att.tmp_class);
elmTMP.setAttribute('type', 'text/css');
elmTMP.setAttribute('rel', 'stylesheet');
document.head.appendChild(elmTMP);
// Adding script element
elmTMP = document.createElement('script');
elmTMP.setAttribute('id', this.att.id.script);
elmTMP.setAttribute('type', 'text/javascript');
document.head.appendChild(elmTMP);
// Adding temp script element
elmTMP = document.createElement('script');
elmTMP.setAttribute('id', this.att.id.tmp_script);
elmTMP.setAttribute('class', this.att.tmp_class);
elmTMP.setAttribute('type', 'text/javascript');
document.head.appendChild(elmTMP);
// Checking the environment
if (
document.getElementById(this.att.id.style) === null ||
document.getElementById(this.att.id.tmp_style) === null ||
document.getElementById(this.att.id.script) === null ||
document.getElementById(this.att.id.tmp_script) === null
) return 0;
if (
document.getElementById(this.att.id.tmp_style).className.indexOf(this.att.tmp_class) < 0 ||
document.getElementById(this.att.id.tmp_script).className.indexOf(this.att.tmp_class) < 0
) return 0;
return 1;
},
// .......... [-] Get file content if file exists
get: function (pthIN) {
var reqTMP = new XMLHttpRequest();
reqTMP.open('GET', pthIN, false);
reqTMP.send(null);
if (reqTMP.status !== 200) return 0;
return reqTMP.response;
},
// .......... [-] Add content to head tags
add: function (txtIN, catIN) {
var attTMP = null;
switch (catIN) {
case 'css':
attTMP = this.att.id.style;
break;
case 'tmp_css':
attTMP = this.att.id.tmp_style;
break;
case 'js':
attTMP = this.att.id.script;
break;
case 'tmp_js':
attTMP = this.att.id.tmp_script;
break;
}
if (attTMP === null) return 0;
document.getElementById(attTMP).innerHTML += txtIN;
return 1;
},
// .......... [+] Load core module
load: function (pthIN, catIN) {
var valTMP = this.get(pthIN);
if (valTMP === 0) return 0;
if (this.add(valTMP, catIN) === 0) return 0;
return 1;
},
//// .......... Check if object is defined
//check: function (objIN) {
// if (typeof objIN !== 'object') return 0;
// return 1;
//},
};
All js files are same this two (changing the name)
/*
FrameBee Framework version 0.2
THE MANAGER . Resources Manager
*/
objManager = {};
or this one
/*
FrameBee Framework version 0.2
THE LUMBERJACK . Global logger
*/
objLumberjack = {};
here the script tag result
<script class="FrameBee_Temp" id="FrameBee_Head_Script_Temp" type="text/javascript">
/*
FrameBee Framework version 0.2
THE MANAGER . Resources Manager
*/
objManager = {};
/*
FrameBee Framework version 0.2
THE LUMBERJACK . Global logger
*/
objLumberjack = {};
/*
FrameBee Framework version 0.2
THE RECRUITER . Resources Loader
*/
objRecruiter = {};
/*
FrameBee Framework version 0.2
THE SAGE . Classes guard
*/
objSage = {};
/*
FrameBee Framework version 0.2
THE ARCHITECT . Style definition
*/
objArchitect = {};
/*
FrameBee Framework version 0.2
THE AGENT . Style applyer
*/
objAgent = {};
</script>
Here a live example of the code
回答1:
There is a big difference between loading and executing. The best place to check all objects are ready is on DOMContentLoaded event.
回答2:
I would use Javascript to load all core modules but I will change to JQuery. The problem is related to the xmlhttprequest method plus the innerHtml method. First time, the browser interpret the code inside. From second on it just add the content. To continue on this way it would be better to create an element (script) each time and append it to the head
var elm = document.createElement('script');
elm.innerHtml = //content retrieved;
document.head.appendChild(elm);
来源:https://stackoverflow.com/questions/30963361/cascading-object-declaration-gives-undefined-typeof-from-second-object-on