2012-01-13 68 views
2

我一直在用document.write和onLoad函數掙扎。document.write,onload和可變範圍問題

如果你考慮一個JS代碼,像這樣的=>

window.i = 0; 
console.log(i + " //should be 0"); 

document.write("<scr"+"ipt onLoad='onA1Ready()' src='a1.js'><\/sc"+"ript>"); 

function onA1Ready(){ 
    document.write("<scr"+"ipt onLoad='onA2Ready()' src='a2.js'><\/sc"+"ript>"); 
} 

function onA2Ready(){ 
    console.log(i + " //should be 2"); 
} 

和a1.js beeing這樣=>

i++; 
console.log(i + " //should be 1"); 

和a2.js beeing頗爲相似=>

i++; 
console.log(i + " //should be 2"); 

我期望最後的控制檯輸出等於2,但是這裏是我從控制檯中得到的=>

0 //should be 0  test.js (line 2) 
1 //should be 1  a1.js (line 2) 
i is not defined ERROR i++; a2.js (line 1) 
onA2Ready is not defined 

我想這個問題是範圍相關的,但我不知道如何。

如果您有任何關於這裏發生了什麼的想法,那將是非常棒的。

回答

1

我在Chrome 16上測試過,一切按預期運行。但是,在最新的FF中,我得到了你所描述的錯誤。

我的建議是停止使用邪惡document.write()動態加載腳本。而是使用DOM方法。我已經寫了一個小功能myLoader(),可以幫助你

window.i = 0; 
console.log(i + " //should be 0"); 

var myLoader = function(filename, fun) { 
    var head = document.getElementsByTagName('head')[0], 
     script = document.createElement('script'); 
    script.type= 'text/javascript'; 
    script.src = filename; 
    if(typeof fun === 'function'){ script.onload = fun; } 
    head.appendChild(script); 
}; 


myLoader('a1.js', function(){ 
    myLoader('a2.js', function() { 
    console.log(i + " //should be 2"); 
    }); 
}); 

試試吧。

輸出I得到

0 //should be 0   a0.js (line 2) 
1 //should be 1   a1.js (line 2) 
2 //should be 2   a2.js (line 2) 
2 //should be 2   a0.js (line 17) 
+0

似乎很大,我給它一個嘗試 非常感謝 – Erwin 2012-01-13 08:29:59

+0

偉大的作品再次感謝 – Erwin 2012-01-13 08:33:40

+0

記得投票這是你的答案;。!) – jaime 2012-01-13 08:34:11

1

首先我會強烈建議不要使用document.write。這是混亂和不必要的。

添加腳本標籤,因此是更好的處理:

var addScriptWithOnLoad = function(src, fn) { 
    var s = document.createElement('script'); 
    s.setAttribute('type', 'text/javascript'); 
    s.setAttribute('src', src); 
    s.onload = fn; 
    document.head.appendChild(s); 
}; 

接下來,你真的不應該使用這樣的全球範圍內,你是依靠瀏覽器踢得好看,這是從來沒有一個安全的賭注。你應該在功能之間傳遞數據。然而,這有點超出了這個答案的範圍。

以下腳本標籤,放置在web page的頭部,產生你想要的結果

<script type="text/javascript"> 
    window.i = 0; 
    var addJS = function(src, fn) { 
     var s = document.createElement('script'); 
     s.setAttribute('src', src); 
     s.setAttribute('type', 'text/javascript'); 
     s.onload = fn; 
     document.head.appendChild(s); 
    }; 

    console.log(i + " //should be 0"); 

    var fn1 = function() { 
     console.log(); 
     addJS('a2.js', fn2); 
    }; 

    var fn2 = function() { 
     console.log(i + " //should be 2"); 
    }; 

    addJS('a1.js', fn1); 
</script> 
+0

我嘗試以下 'window.i = 0; document.write(「<\/sc"+"ript>」); function onA1Ready(){ \t document.write(「<\/sc"+"ript>」); } function onA2Ready(){ \t console.log(window。i +「// onA2Ready」); }' with a1.js => 'window.i ++; console.log(window.i +「//a1.js」);' and a2.js => 'window.i ++; 的console.log(window.i + 「//a2.js」);' 控制檯日誌此=> '的NaN // a2.js a2.js(線2) onA2Ready不defined' – Erwin 2012-01-13 08:14:26

+0

關於全球範圍,我不會在實際項目中這樣做,這個片段只是爲了在這裏展示我的問題。無論如何,你的解決方案很好,與jm相當 - 我想。再次感謝,Erwin – Erwin 2012-01-13 10:50:25

0

我懷疑onA1Ready()被調用的onLoad其寫入到被調用的onLoad另一個函數,它從來沒有被稱爲該文件已被加載。

+0

嗨,感謝您的幫助,我是一個新手用javascript :( 控制檯輸出說:onA2Ready沒有定義,是不是說,功能beeing叫,但不知何故不可見?那個特定的範圍內 – Erwin 2012-01-13 08:17:35