最近因为工作需要做了一个js自动导入的插件,一开始很天真的以为动态创建个script添加到head中就ok了,试了之后才发现了问题,就是如果同时引入了多个js文件,而且后一个文件中用到了前一个文件中的变量,那就会报错,靠~~悲催了,就是说js如果动态加载(非浏览器加载因为浏览器加载时同步加载的会等待前一个js加载完成后才进行下一个js加载,这样就不会出现问题)那加载的文件是异步进行的,难怪啊!然后在网上找了些资料说用ajax同步加载,然后我试了真可以,下面就是我的代码分享出来给大家,但是注意这样加载出来的js有一个致命的弱点,就是没法再浏览器上调试- - !!!!!以后再寻找解决方案吧,先贴代码:

js主文件importComJs.js:

**
* Created by carlos on 2015/5/19.
* QImport 导入帮助函数,可以很方便的导入指定的js、css文件。但是需要注意的是,这样导入的js将无法调试,暂时没有找到解决方案--!
* 使用方法先把此文件引入,必须放在head中的最前面导入,
* <script src="../js/importComJs.js" id="QImport"></script>
* id必须是QImport,否则无效
* 然后加入
* <script>
* QImport.init(customscripts);
* </script>
* customscripts参数为:外加的引入文件配置,可以不填。但填写必须遵守QImport.IMPORTSCRIPTS的写法。
* 如果不想手动初始化引入函数,可以这样写:
* <script src="../js/importComJs.js" id="QImport" data-auto="true"></script>
* 这里的 data-auto为true时候才会自动初始化,否则需要手动初始化。
* 使用上自动初始化,不用担心引入顺序问题,后面的其他js、css文件按正常引用就可以了。
* 注意:importComjs文件必须第一个引入,否则将出现引用找不到的问题。
* 新增属性:
* data-config:自定义配置文件名,默认为“importConfig.json”
* data-personalconfigname:自定义个性化配置名称,在配置文件中的“personalscripts”中配置
* 注意:配置加载顺序是:importscripts最高、personalscripts其次、customscripts最低。如果引入的次序不对会引起空指针报错哦^^!
*/ /**
* 同步加载js脚本
* @param id 需要设置的<script>标签的id
* @param url js文件的相对路径或绝对路径
* @return {Boolean} 返回是否加载成功,true代表成功,false代表失败
*/
(function(){
QImport = {
self:{
obj:function(){
return document.getElementById('QImport'); //获取script的id,如果项目中实在是有冲突不得不改,那就该这个“QImport”吧!
},
auto:function(){
return eval(this.getAttr('data-auto')); //是否开启自动初始化模式,默认为false
},
config:function(){
return this.getAttr('data-config'); //自定义配置文件名,默认为“importConfig.json”
},
personal:function(){
return this.getAttr('data-personalconfigname') //自定义个性化配置名称,在配置文件中的“personalscripts”中配置。
},
src:function(){
return this.getAttr('src'); //此文件位置,不多说
},
getAttr:function(attrName){
var attrValue = undefined;
try{
attrValue = this.obj().getAttribute(attrName);
}
catch(e){}
return attrValue;
},
relationpath:function(){
var src = this.src();
var re = /^[..\/]*/;
return src.match(re)[0];
},
path:function(filename){
var src = this.src();
var temp = src.split('/');
var path = "";
temp.pop();
temp.push(filename);
return temp.join('/');
}
},
autoinit:function(){
if(this.self.auto()){
this.init();
}
},
getpath:function(p){
var path = this.self.relationpath()+p;
return path.replace('//','/');
},
init:function(customscripts){ //导入文件的主方法
this.extend(customscripts);
var IMPORTSCRIPTS = this.IMPORTSCRIPTS;
var head = document.getElementsByTagName("head").item(0);
var meta = document.createElement('meta'); //自动添加web手机适应代码;
meta.name = 'viewport';
meta.content = 'width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no';
head.insertBefore(meta, head.childNodes[0]);
var re = /^http[s]?:\/\//i;
for(var i=0;i<IMPORTSCRIPTS.length;i++){
loadpath = IMPORTSCRIPTS[i].url;
if(!re.test(IMPORTSCRIPTS[i].url)){
loadpath = this.getpath(IMPORTSCRIPTS[i].url);
}
if(IMPORTSCRIPTS[i].type=="script"){
var flag = this.loadJS(loadpath,loadpath,i+1)
if(!flag){
alert('loading path:"'+loadpath+'" failed,May be lost "http(s)://"');
}
}
else if(IMPORTSCRIPTS[i].type=="css"){
var csss = document.createElement('link')
csss.href = this.getpath(IMPORTSCRIPTS[i].url);
csss.rel = 'stylesheet';
head.insertBefore(csss, head.childNodes[i+1]);
}
}
},
extend:function(customscripts){ //自定义扩展方法,仅适用当前对象
if(!(customscripts instanceof Array)) return;
var IMPORTSCRIPTS = this.IMPORTSCRIPTS;
for(var i=0;i<customscripts.length;i++){
var flag = false;
for(var j=0;j<IMPORTSCRIPTS.length;j++){
if((IMPORTSCRIPTS[j].type==customscripts[i].type)&&(IMPORTSCRIPTS[j].url==customscripts[i].url)){
flag = true;
break;
}
}
if(!flag){
this.IMPORTSCRIPTS.push({type:customscripts[i].type,url:customscripts[i].url});
}
}
},
ajax:function(url){ //ajax原始方法,这里仅可以同步请求
var xmlHttp = null;
if(window.ActiveXObject)//IE
{
try {
//IE6以及以后版本中可以使用
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
//IE5.5以及以后版本可以使用
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
else if(window.XMLHttpRequest)//Firefox,Opera 8.0+,Safari,Chrome
{
xmlHttp = new XMLHttpRequest();
}
//采用同步加载
xmlHttp.open("GET",url,false);
//发送同步请求,如果浏览器为Chrome或Opera,必须发布后才能运行,不然会报错
xmlHttp.send(null);
//4代表数据发送完毕
if ( xmlHttp.readyState == 4 ){
//0为访问的本地,200到300代表访问服务器成功,304代表没做修改访问的是缓存
if((xmlHttp.status >= 200 && xmlHttp.status <300) || xmlHttp.status == 0 || xmlHttp.status == 304){
return xmlHttp.responseText;
}
else{
return false;
}
}
else{
return false;
}
},
loadJS:function(id,url,rank){ //加载js文件
var importText = this.ajax(url);
if(!importText) return false;
var myHead = document.getElementsByTagName("HEAD").item(0);
var myScript = document.createElement( "script" );
myScript.language = "javascript";
myScript.type = "text/javascript";
myScript.id = id;
try{
//IE8以及以下不支持这种方式,需要通过text属性来设置
myScript.appendChild(document.createTextNode(importText));
}
catch (ex){
myScript.text = importText;
}
myHead.insertBefore(myScript, myHead.childNodes[rank]);
return true;
},
template:{ //加载模板文件,现在仅在引入“jquery”的情况下可用。
parent:this, //父类this引用
_setparent:function(){ //把父类的this赋给子方法的parent
this.template.parent = this;
},
includeTagName:'include', //引入时候用的标签:<include url="head.html"></include>
init:function(){
this.include();
},
include:function(){
var includes = document.getElementsByTagName(this.includeTagName);
for(var i=0;i<includes.length;i++){
var url = includes[i].getAttribute('url');
var includeHtml = this.parent.ajax(url);
var parent = includes[i].parentNode;
var newEs = this.parseDom(includeHtml);
for(var j=0;j<newEs.length;j++){
parent.insertBefore(newEs[j], includes[i])
}
}
while(true){
if(includes.length==0) break;
includes[0].remove();
}
},
parseDom:function(str){
var obj = document.createElement('div');
obj.innerHTML = str;
return obj.childNodes;
}
},
initparent:function(){ //子类中想用父类中的方法必须通过此方法初始化以下,还必须引入如template的parent和_setparent
this.template._setparent.call(this);
},
getimportjson:function(){ //获取的配置json
var configName = this.self.config(); //共用配置
if(configName) this.configname = configName;
var configpath = this.self.path(this.configname);
var confJsonStr = this.ajax(configpath);
if(!confJsonStr){
alert('config file path:"'+configpath+'" can not be loaded');
return;
}
this.confJson = eval('('+confJsonStr+')');
importarr = this.confJson.importscripts;
if(importarr instanceof Array){
this.IMPORTSCRIPTS = this.confJson.importscripts;
}
this.getpersonalarr();
},
getpersonalarr:function(){ //获取个性化配置arr
var personalConfigName = this.self.personal();
if(!personalConfigName) return;
this.personalconfigname = personalConfigName;
var personalarr = this.confJson.personalscripts[personalConfigName];
if(personalarr instanceof Array){
this.extend(personalarr)
}
},
confJson:{},
IMPORTSCRIPTS:[],
configname:'importConfig.json'
}
QImport.getimportjson();
QImport.autoinit();
QImport.initparent();
try{
$(function(){
QImport.template.init();
});
}
catch(e){} })();

下面是配置文件,importConfig.json:

{
importscripts:[
{
type: 'script',
url: 'js/jquery-1.9.1/jquery-1.9.1.min.js'
},{
type: 'script',
url: 'js/mui.min.js'
},{
type: 'css',
url: 'css/mui.min.css'
},{
type: 'script',
url: 'js/json2.js'
}
],
personalscripts:{
test:[
{
type:'script',
url:'js/test.js'
}
]
}
}

注意配置文件必须和导入方法js在同一个路径底下。

以上就是我个人封装的引入js、css的代码,希望和大家交流下,有什么问题希望大家能不吝指教!

js插件动态加载js、css解决方案的更多相关文章

  1. js怎么动态加载js文件(JavaScript性能优化篇)

    下面介绍一种JS代码优化的一个小技巧,通过动态加载引入js外部文件来提高网页加载速度 [基本优化] 将所有需要的<script>标签都放在</body>之前,确保脚本执行之前完 ...

  2. 动态加载js css 插件

    简介 动态加载js,css在现在以及将来肯定是很重要的.目前来看前端代码编写的业务量已经远远超过后端编写的.随着对用户体验度逐渐增强,前端业务复杂,加载速度变得很慢很慢.为了解决这个问题,目前出现的两 ...

  3. 动态加载js和css

    开发过程中经常需要动态加载js和css,今天特意总结了一下常用的方法. 1.动态加载js 方法一:动态加载js文件 // 动态加载js脚本文件 function loadScript(url) { v ...

  4. 动态加载js,css(项目中需要的)

    最近做的一个项目需要加入百度统计,大家都知道百度统计在页面引用就是一坨js,实现方法很简单引用到页面就ok了. 那么问题来了,虽然我不知道百度统计的原理是啥,我的测试服引用了百度统计,百度统计账号里面 ...

  5. 动态加载JS函数

    一般性的,当我们需要加载js文件的时候都会使用script标签来实现,类似于如下代码: 代码如下: <script type="text/javascript" src=&q ...

  6. 动态加载js,css

    今天项目中需要用到动态加载 CSS 文件,经过一番折腾终于搞定,回家整理了一下,顺便融合了动态加载 JS 的功能写成了一个对象,先上代码: var dynamicLoading = { css: fu ...

  7. JS动态加载 js css

    1.动态加载js function loadScript( url ){ var script = document.createElement( "script" ); scri ...

  8. js动态加载js css文件,可以配置文件后辍,防止浏览器缓存

    js的引用,在浏览器,或微信上访问经常会遇到文件改了,但就是没有更新的问题,使用此函数可以轻松解决缓存问题只需要把js的引用方式改为使用此函数加载即可 源码如下: /** * js动态加载js css ...

  9. jquery动态加载js/css文件方法

    先来看jquery自带的getSrcript文件 方法 代码如下 复制代码 $.getScript(url,callback) 实例 代码如下 复制代码 var testVar = 'New JS l ...

随机推荐

  1. Unicode与 utf8的互相转换

    <?php function unicode_encode($name) { $name = iconv('UTF-8', 'UCS-2', $name); $len = strlen($nam ...

  2. iOS新建项目基本配置

    项目整体同xib+代码的方式 1.调整项目文件结构 2.将资源图片导入工程 General->LaunchScreen 修改 3.App名称修改 info->Bundle name 4.删 ...

  3. 数字证书KeyTool使用(第二篇)

    http://my.oschina.net/frankies/blog/344914 J2SDK提供了keytool命令行工具,可以根据指定的参数来创建数字证书.生成的证书或证书库默认保存在命令行当前 ...

  4. 一个寻找.jar 和.zip文件中class文件的工具

    相信很多人跟我一样,苦于在各种包之间,不知道Class存在什么地方,为此,自己写了一个小工具,来寻找目录下的Class文件 支持 目录查询,支持带包路径查询 入口Entrance.java packa ...

  5. FontCombobox 和FontSizeCombobox

    附件:http://files.cnblogs.com/xe2011/WindowsFormsFontCombox.rar 自定义组件字体组合框 自定义组件字体组合框如何使用 自定义组件字体大小组合框 ...

  6. FastDFS、nginx配置手记

    第一部分   FastDFS介绍 1.FastDFS是什么 FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能 ...

  7. [D3] 7. Quantitative Scales

    # Quantitative Scales var colorScale = d3.scale.quantile() .domain([d3.max(dataset) / 4, d3.max(data ...

  8. hdu2007

    import java.util.*;class Main{public static void main(String args[]){Scanner cin=new Scanner(System. ...

  9. Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)

    Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下:       1.Vi ...

  10. angularjs 根据变量改变 动态加载模板

    directive return { restrict: 'E', replace: true, templateUrl: 'app/view/order.html', link: function ...