JavaScript无非就是script标签引入页面,但当项目越来越大的时候,单页面引入N个js显然不行,合并为单个文件减少了请求数,但请求的文件体积却很大。这时候最好的做法就是按需引入,动态引入组件js和样式,文件load完成后调用callback,运行js。代码还是很简便的。
1. 判断文件load完成。加载状态ie为onreadystatechange,其他为onload、onerror
01 |
if (isie){
|
02 |
Res.onreadystatechange = function (){
|
03 |
if (Res.readyState == 'complete' || Res.readyState == 'loaded' ){
|
04 |
Res.onreadystatechange = null ;
|
05 |
callback();
|
06 |
_self.loadedUi[modelName] = true ;
|
07 |
}
|
08 |
}
|
09 |
} |
10 |
else {
|
11 |
Res.onload = function (){
|
12 |
Res.onload = null ;
|
13 |
callback();
|
14 |
_self.loadedUi[modelName] = true ;
|
15 |
}
|
16 |
Res.onerror = function (){
|
17 |
throw new Error( 'res error:' + modelName+ '.js' );
|
18 |
}
|
19 |
} |
2. 所有组件的命名最好保持一致,callback调用也比较方便。还可以根据需要增加参数比如: requires,依赖于那些文件;style,true || false,是否加载样式,等等。
3. 移除操作也可以有,移除script、style标签、delete组件
001 |
( function (window,undefined){
|
002 |
if (!window.ui) {
|
003 |
window.ui = {};
|
004 |
}
|
005 |
//动态加载ui的js
|
006 |
window.bus = {
|
007 |
config : {
|
008 |
version : window.config.version,
|
009 |
cssPath : window.config.resServer + '/css/v3/ui' ,
|
010 |
jsPath : window.config.resServer + '/js/v2/ui'
|
011 |
},
|
012 |
loadedUi : {},
|
013 |
readyStateChange : function (){
|
014 |
var ua = navigator.userAgent.toLowerCase();
|
015 |
return ua.indexOf( 'msie' ) >= 0;
|
016 |
},
|
017 |
loadRes : function (modelName,prames,callback){
|
018 |
var _self = this ;
|
019 |
var Res = document.createElement(prames.tagName);
|
020 |
for ( var k in prames){
|
021 |
if (k != 'tagName' ){
|
022 |
Res.setAttribute(k,prames[k],0);
|
023 |
}
|
024 |
}
|
025 |
document.getElementsByTagName( 'head' )[0].appendChild(Res);
|
026 |
027 |
if ( this .readyStateChange()){
|
028 |
Res.onreadystatechange = function (){
|
029 |
if (Res.readyState == 'complete' || Res.readyState == 'loaded' ){
|
030 |
Res.onreadystatechange = null ;
|
031 |
callback();
|
032 |
_self.loadedUi[modelName] = true ;
|
033 |
}
|
034 |
}
|
035 |
} else {
|
036 |
Res.onload = function (){
|
037 |
Res.onload = null ;
|
038 |
callback();
|
039 |
_self.loadedUi[modelName] = true ;
|
040 |
}
|
041 |
Res.onerror = function (){
|
042 |
throw new Error( 'res error:' + modelName+ '.js' );
|
043 |
}
|
044 |
}
|
045 |
},
|
046 |
removeUi : function (modelName){
|
047 |
if (!modelName){
|
048 |
return true
|
049 |
};
|
050 |
this .loadedUi[modelName] = false ;
|
051 |
052 |
var head = document.getElementsByTagName( 'head' )[0];
|
053 |
var model_js = document.getElementById( 'J_model_' +modelName + '_js' );
|
054 |
var model_css = document.getElementById( 'J_model_' +modelName + '_css' );
|
055 |
if (model_js && model_css){
|
056 |
delete window.ui[modelName];
|
057 |
head.removeChild(model_js);
|
058 |
head.removeChild(model_css);
|
059 |
return true ;
|
060 |
} else {
|
061 |
return false ;
|
062 |
}
|
063 |
},
|
064 |
loadUi : function (modelName,callback,setting){
|
065 |
if (!modelName){
|
066 |
return true
|
067 |
};
|
068 |
callback = callback || function (){};
|
069 |
if ( this .loadedUi[modelName] == true ){
|
070 |
callback();
|
071 |
return true
|
072 |
}
|
073 |
074 |
var deafult_setting = {
|
075 |
style : true ,
|
076 |
js : true ,
|
077 |
requires : []
|
078 |
}
|
079 |
for ( var key in setting){
|
080 |
deafult_setting[key] = setting[key];
|
081 |
}
|
082 |
deafult_setting[ 'style' ] === true && this .loadRes(modelName,{
|
083 |
id : 'J_model_' +modelName + '_css' ,
|
084 |
name : modelName,
|
085 |
tagName : 'link' ,
|
086 |
type : 'text/css' ,
|
087 |
rel : 'stylesheet' ,
|
088 |
href : this .config.cssPath + '/' + modelName + '.css?v=' + this .config.version
|
089 |
});
|
090 |
091 |
deafult_setting[ 'js' ] === true && this .loadRes(modelName,{
|
092 |
id : 'J_model_' +modelName + '_js' ,
|
093 |
name : modelName,
|
094 |
tagName : 'script' ,
|
095 |
type : 'text/javascript' ,
|
096 |
src : this .config.jsPath + '/' + modelName + '.js?v=' + this .config.version
|
097 |
},callback);
|
098 |
if (deafult_setting.requires.length > 0){
|
099 |
for ( var i=0,len = deafult_setting.requires.length;i < len;i++){
|
100 |
this .loadUi(deafult_setting.requires[i]);
|
101 |
}
|
102 |
}
|
103 |
}
|
104 |
}
|
105 |
})(window) |
使用方法:
01 |
// load comment for feed |
02 |
window.bus.loadUi( 'new_comment_feed' , function (){
|
03 |
window.ui.new_comment_feed($( "#J_newsList" ));
|
04 |
},{ |
05 |
style : false ,
|
06 |
requires:[ 'emoticon' , 'addFriend' ]
|
07 |
}); |
08 |
09 |
// load new yy ui |
10 |
window.bus.loadUi( 'yy' , function (){
|
11 |
window.ui.yy(options);
|
12 |
},{ |
13 |
style: false ,
|
14 |
requires:[ 'emoticon' ]
|
15 |
}); |
16 |
17 |
// load photoLightbox |
18 |
window.bus.loadUi( 'photoLightbox' , function (){
|
19 |
window.ui.photoLightbox(options.urlAjaxGetFriendPhoto, options.urlCommentOtherPhoto,$( "#J_newsList" ),options.myUid,options.myName);
|
20 |
}); |