- var head = document.head
- || document.getElementsByTagName("head")[0]|| document.documentElement;
- var script = document.createElement("script");
- script.setAttribute("type","text/javascript");
- script.setAttribute("src",url);
- //////////////////////////好像只有IE支持
- script.onreadystatechange=function(){
- if(document.readyState=='complete'){
- callback();
- }
- };
- / //////////
- head.insertBefore(script, head.firstChild);
這種方式就是創建一個script對象,在設置script的src屬性,這種方式最簡單。但是上邊利用加載狀態來處理,他的兼容不是很好。
其實這裏把open裏面設置爲false就是同步加載了,同步加載不需要設置onreadystatechange事件。
方法六:XMLHttpRequest/ActiveXObject同步加載
在這裏我把一些情況考慮在內,寫成了一個方法,封裝爲loadJS.js,方便以後直接調用,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
/** * 同步加載js腳本 * @param id 需要設置的< script >標籤的id * @param url js文件的相對路徑或絕對路徑 * @return {Boolean} 返回是否加載成功,true代表成功,false代表失敗 */ function loadJS(id,url){ 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) { 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(xmlHttp.responseText)); } catch (ex){ myScript.text = xmlHttp.responseText; } myHead.appendChild( myScript ); return true; } else { return false; } } else { return false; } } |
此處考慮到了瀏覽器的兼容性以及當爲Chrome、Opera時必須是發佈,註釋還是寫的比較清楚的,以後需要加載某個js文件時,只需要一句話就行了,如loadJS("myJS","package.js")。方便實用。
如果想要實現不發佈還非要兼容所有瀏覽器,至少我還沒找出這樣的同步加載的辦法,我們只能通過異步加載開出回調函數來實現。
方法七:回調函數方式
在同一個文件夾下面創建一個function7.html,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
< html > < head > < title >動態加載js</ title > < meta http-equiv = "Content-Type" content = "text/html;charset=UTF-8" > < script type = "text/javascript" > function init() { //加載package.js文件,設置script的id爲yy loadJs("yy","package.js",callbackFunction); } function callbackFunction() { functionOne(); } function loadJs(sid,jsurl,callback){ var nodeHead = document.getElementsByTagName('head')[0]; var nodeScript = null; if(document.getElementById(sid) == null){ nodeScript = document.createElement('script'); nodeScript.setAttribute('type', 'text/javascript'); nodeScript.setAttribute('src', jsurl); nodeScript.setAttribute('id',sid); if (callback != null) { nodeScript.onload = nodeScript.onreadystatechange = function(){ if (nodeScript.ready) { return false; } if (!nodeScript.readyState || nodeScript.readyState == "loaded" || nodeScript.readyState == 'complete') { nodeScript.ready = true; callback(); } }; } nodeHead.appendChild(nodeScript); } else { if(callback != null){ callback(); } } } </ script > </ head > < body > < input type = "button" value = "測試按鈕" onclick = "init()" /> </ body > </ html > |
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();
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);
};
var rootObject=document.getElementById("divId");
var oScript = document.createElement( "script" );
oScript.type = "text/javascript";
oScript.src = test.js; //test.js方法中有一個方法function test(){alert("test");}
rootObject.appendChild(oScript);
引用文件時賦予ID 使用jquery刪除 即可 $(id).remove();
刪除文件引用並沒什麼用
建議刪除文件引用後 要釋放該引用文件產生內存
在一個JS文件中引用另一個JS文件
注意:在html文件導入a.js時,應該把script></script寫在/body>後面,否則 document.write()方法有問題。在載入頁面後,瀏覽器輸出流自動關閉;在此之後,任何一個對當前頁面進行操作的 document.write()方法將打開—個新的輸出流。它將清除當前頁面內容(包括源文檔的任何變量或值),因此,假如希望用腳本生成的HTML替換當前頁面,就必須把HTML內容連接起來賦給一個變量、使用一個document.write()方法完成寫操作,不必清除文檔並打開一個新數據流,一 個document.write()調用就可完成所有的操作。
關於document.write()方法還有一點要說明的是它的相關方法document.close()。腳本向窗口(不管是本窗口或其他窗口)寫完內容後.必須關閉輸出流。在延時腳本的最後一個document.write()方法後面.必須確保含有document.close()方法,不這樣做就不能顯示圖片和表單。並且,任何後面調用的document.write()方法只會把內容追加到頁面後,而不會清除現有內容來寫入新值。
在當前JS文件中加入:
document.write("script language='javascript' src='js/jquery-1.3.1.min.js'></script");
例如:在a.js中要引用b.js的函數
a.js內容如下:
document.write("script language='javascript' src='b.js'></script");
function test()
{
b();
}
b.js內容如下:
function b()
{
alert("b");
}
***********************************************************
在處理較爲複雜的頁面邏輯時可能用到多個js文件,比如將實現特定功能的js文件分開放在不同的文件裏面,但是我又不希望在頁面引用時多個js文件,所以就考慮在一個js文件裏面引用另一個js文件了。
具體實現:
HTML文件:
html>
<body>
<input type="button" value="ok" onclick="javascript:b()">
</body>
<!--這裏引用要放在body下面-->
<script language="JAVASCRIPT" src='b.js'>
</script>
</html
b.js代碼: 程序代碼
new_element=document_createElement_x_x_x_x_x("script");
new_element.setAttribute("type","text/javascript");
new_element.setAttribute("src","a.js");
document.body.a(new_element);
function b()
{ a();}
a.js代碼: 程序代碼
function a()
{ alert("a");}
另外例子
<script>
var obj=document.getElementByIdx_x_x_x("某控件");
var ele=document_createElement_x_x_x("script");
ele.src="路徑";
obj.a(ele);
一個比較全部在動態加方法
/*
動態加載js v1.0 by:dum 2012-03-17 www.hzhuti.com
用法:src="webJsBase.js?load=a,b"
注:加載本目錄下js
*/
var webJsBase = {
require: function(libraryName) {
document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
},
load: function(defaultLoad) {
if((typeof Prototype=='undefined')||(typeof Element == 'undefined')||(typeof Element.Methods=='undefined'))
throw ('prototype lib 加載失敗!');
if(typeof defaultLoad=='undefined')defaultLoad='';
var js = /webJsBase.js(?.*)?$/;
$$('head script[src]').findAll(function(s) {
return s.src.match(js);
}).each(function(s) {
var path = s.src.replace(js, '');
var includes = s.src.match(/?.*load=([a-zA-Z0-9_,]*)/);
(includes ? includes[1] : defaultLoad).split(',').each(function(include) {
webJsBase.require(path + include + '.js');
});
});
}
};
webJsBase.load(); //這裏參數可以指定默認要加載的js文件
這是最簡單的方法在加載完後再利用直接document.write 如下圖。
<script language="javascript">
document.write("<script src='test.js'></script>");
</script>
給script加個id再去動態改變已有script的src 屬性
代碼如下 複製代碼
<script src='' id="s1"></script>
<script language="javascript">
s1.src="test.js"
</script>
這裏利用getElementsByTagName('HEAD')動態創建 script元素
<script>
var oHead = document.getElementsByTagName('HEAD').item(0);
var oScript= document.createElement("script");
oScript.type = "text/javascript";
oScript.src="test.js";
oHead.appendChild( oScript);
</script>
還可以這樣嘗試一下,自定一個函數
function include(src) {
HTMLCode = '<script language="javascript" src="' + src + '"></script>';
document.write(HTMLCode);
}
調用方法,這樣看上去就你php的include函數了
代碼如下 複製代碼
include(baseDir + "/Prototype.js");
include(baseDir + "/Map.js");
include(baseDir + "/MapEvent.js");
include(baseDir + "/model/MapModel.js");
include(baseDir + "/model/MapType.js");
include(baseDir + "/model/Tile.js");
還有朋友說可以使用ExtJs4 動態加載js這裏我就不介紹了,上面的方法足夠讓你實現動態加載js了.
所以在採用這類方法動態加載Js 的同時,主界面的Js腳本是繼續執行的,所以可能出現通過異步加載的Js代碼得不到預期的效果的情況。
這時候可以考慮採用Ajax加載Js的方法。