==
jQuery.ajax({
url : src,
type : "GET",
dataType : "script",
async : false,
global : false,
"throws" : true
});
jQuery.ajax({
url : src,
type : "GET",
dataType : "script",
async : false,
global : false,
"throws" : true
});
var src = '3.js';
var xhr = new window.XMLHttpRequest();
xhr.open('GET',src,false);
xhr.send(null);
var responseText = xhr.responseText;
function globalEval(data){
window["eval"].call(window, data);
}
globalEval(responseText);
//var $a = aa();
但是,采用ajax请求的方式不是我想要的,跟我说的关系不大。已通过回调函数的方式将问题解决,但效果不理想,疑惑仍然存在。为什么要使用动态加载js文件?
主要是因为管理类的系统,如果功能太多并且js文件也较多较大。如果使用进入系统就加载所有的js,那么在进入系统的时候,可能等半天都出不来界面。所以本人考虑在进入系统时,只加载一些必须的js文件,如:jquery等。用户点击某个菜单,这个时候才加载该菜单功能所需要的js文件。这样就能加快系统响应速度。另外,便于统一管理js或者css文件的引入
采用jquery的方式动态加载js,这个实现起来太简单了,但是问题也明显,这种方式在浏览器中找不到js文件,在前端根本无法进行调试。js如果太多,你找到你写的那个js文件那够你受的。以下是自己结合网上的知识纯js编写的代码,虽然说勉强实现了想要的效果,但是不够理想,望各位高人指教啊。
var JSLoader = {
browser : {
ie : /msie/.test(window.navigator.userAgent.toLowerCase()),
moz : /gecko/.test(window.navigator.userAgent.toLowerCase()),
opera : /opera/.test(window.navigator.userAgent.toLowerCase()),
safari : /safari/.test(window.navigator.userAgent.toLowerCase())
},
call : (function() {
var _file_array = new Array();//保存已添加的文件
/**
* 判断文件是否存在
* @param tag 元素名称
* @param url 文件url
* @return 如果存在,返回true;否则,返回false
*/
function hasFile(tag, url) {
var contains = false;
var files = document.getElementsByTagName(tag);
var type = tag == "script" ? "src" : "href";
for ( var i = 0, len = files.length; i < len; i++) {
if (files[i].getAttribute(type) == url) {
contains = true;
break;
}
}
for(var i=0,len=_file_array.length;i<len;i++){
if(url==_file_array[i]){
contains = true;
break;
}
}
return contains;
}
/**
* 串行加载所有js文件
* 如果所加载的js文件不存在页面中,则js文件一个接一个加载完成只至最后一个js文件加载完成后,执行回调函数
* 如果所加载的js文件已经加载过,则直接执行回调函数。
* @param scripts:['jsFile']
* @param callback:回调函数[可选]
* @paren parent:js文件加载的位置,默认为head
*/
function serielLoadScripts(scripts, callback,parent) {
removeExist(scripts);
if(scripts.length==0){
if(callback) callback();
return;
}
parent = parent || 'head';
var head = document.getElementsByTagName(parent)[0]
|| document.documentElement;
var s = new Array();
var last = scripts.length - 1;
var recursiveLoad = function(i) { // 递归
if(!hasFile("script", scripts[i])){
s[i] = document.createElement("script");
s[i].setAttribute("type", "text/javascript");
s[i].onload = s[i].onreadystatechange = function() {
if (!JSLoader.browser.ie || this.readyState == "loaded"
|| this.readyState == "complete") {
this.onload = this.onreadystatechange = null;
this.parentNode.removeChild(this);
if (i != last)
recursiveLoad(i + 1);
else if (typeof (callback) == "function")
callback();
}
};
s[i].setAttribute("src", scripts[i]);
head.appendChild(s[i]);
}else{
if(callback){
callback();
}
}
};
recursiveLoad(0);
}
/**
* 同步加载JS文件
* 如果所加载的js文件不存在页面中,则将在所有js文件加载完成以后才执行回调函数。
* 如果所加载的js文件已经加载过,则直接执行回调函数。
* @param scripts:['jsFile']
* @param callback:回调函数[可选]
*/
function parallelLoadScripts(scripts, callback,parent) {
removeExist(scripts);
if(scripts.length==0){
if(callback) callback();
return;
}
parent = parent || 'head';
var head = document.getElementsByTagName(parent)[0]|| document.documentElement;
var s = new Array();
var loaded = 0;
for ( var i = 0; i < scripts.length; i++) {
if(!hasFile("script", scripts[i])){
s[i] = document.createElement("script");
s[i].setAttribute("type", "text/javascript");
s[i].setAttribute("src", scripts[i]);
s[i].onload = s[i].onreadystatechange = function() {
if (!JSLoader.browser.ie || this.readyState == "loaded"
|| this.readyState == "complete") {
loaded++;
this.onload = this.onreadystatechange = null;
this.parentNode.removeChild(this);
if (loaded == scripts.length&& typeof (callback) == "function"){
callback();
}
}
};
head.appendChild(s[i]);
_file_array.push(scripts[i]);
}
}
}
function cssLoad(csses,callback){
removeExist(csses);
if(csses.length==0&&callback){
callback();
return;
}
var head = document.getElementsByTagName('head')[0]|| document.documentElement;
var s = new Array();
var loaded = 0;
for ( var i = 0; i < csses.length; i++) {
if (!hasFile("css", csses[i])) {
s[i] = document.createElement("link");
s[i].setAttribute("type", "text/css");
s[i].setAttribute('rel', 'stylesheet');
s[i].setAttribute('href', csses[i]);
s[i].onload = s[i].onreadystatechange = function() {
if (!JSLoader.browser.ie || this.readyState == "loaded"
|| this.readyState == "complete") {
loaded++;
this.onload = this.onreadystatechange = null;
if (loaded == scripts.length
&& typeof (callback) == "function") {
callback();
}
}
};
head.appendChild(s[i]);
_file_array.push(csses[i]);
}
}
}
function removeExist(arr){
for(var i=0,len=arr.length;i<len;i++){
for(var k=0,len_k=_file_array.length;k<len_k;k++){
if(arr[i]==_file_array[k]){
arr.splice(i,1);
}
}
}
}
return {
seriel : serielLoadScripts,
paralle : parallelLoadScripts,
css:cssLoad
};
})()
};
/**
* JS动态导入,外部调用接口
*
* 注意:为了保证动态引入的js文件中的事件能够被正常执行,
* 请将需要执行事件的动作放入回调函数中执行
*
* 以jquery为例:
* 在点击菜单A时,动态引入js文件a.js,b.js,并且生成一个按钮Btn,Btn的onclick事件函数show()位于a.js中。
* 代码如下:
* $(A).click(function(){
* jsLoader(['a.js','b.js'],function(){
* $('<input type="button" value="测试" onclick="show()">').appendTo($(A));
* });
* });
*
* 也可以只是纯粹的引入js。这种情况可能会出现问题。
* 原因:js文件还未加载完成就使用其中的函数或者变量。
* 改写上面例子,代码如下:
* $(A).click(function(){
* jsLoader(['a.js','b.js']);
* });
* $('<input type="button" value="测试" onclick="show()">').appendTo($(A));
* 这样写的话,可能会出现show()未定义,解决方法未找到
*/
var jsLoader = function(scripts,callback,parent,type){
type = type || "parallel";//默认为并行模式
if(type=="seriel"){
JSLoader.call.seriel(scripts,callback,parent);
}else{
JSLoader.call.paralle(scripts,callback,parent);
}
};
/**
* CSS动态导入,外部调用接口
*/
var cssLoader = function(csses,callback){
JSLoader.call.css(csses,callback);
};