2011-11-16 15 views
0

我有2個文件,第一個文件有一些HTML和JS的一部分。第二個文件是主文件,它通過'XmlHttpRequest加載第一個文件。爲什麼瀏覽器不會解析AJAX加載的文件中的JS代碼?

第一個文件是這樣的:

<div> 
    My HTML contents 
</div> 

<script id="my_js_block"> 
function my_function() { 
    alert(9); 
} 
</script> 

第二個文件是這樣的:

<div id="div_ajax_content"> 
    &nbsp; 
</div> 

<script> 
function load_ajax_content() { 
    //synchronously with XmlHttpRequest(...,...,false); 
    //...load and throw the first file into 'div_ajax_content' 
} 

load_ajax_content(); 
my_function(); <-- fails here 
</script> 

如何解決這個問題?

+0

我剛編輯過這個問題。 – jondinham

+0

我想你不能調用這個函數,因爲AJAX調用是異步的。這意味着在調用'my_function()' – GNi33

回答

3

通過innerHTML添加腳本不會運行該腳本。因此你的功能沒有被定義,因此失敗了。相反,我建議分別加載HTML和JS,並使用DOM方法附加JS來將<script>標記放在頁面上,或者eval()來執行返回的文件內容。

+0

eval()是解決方案之一,但我不知道是否有更純粹的方式 – jondinham

+1

'eval()'可以在這裏使用,因爲JS是一個解釋型語言(你不需要編譯它 - 瀏覽器可以提高性能,但這不是必需的),因爲它是一次性的。如果你在一個大循環中使用'eval',那會很糟糕,但對於一次性使用這樣的代碼就沒有問題了。 –

+0

如果我調用eval(「function my_func(){}」)兩次會失敗嗎? (可能是'函數重定義'的錯誤?) – jondinham

4

Ajax是異步的。您的代碼嘗試在XMLHttpRequest完成之前撥打my_function()。做到這一點,而不是:

<script> 
function load_ajax_content() { 
    //...load and throw the first file into 'div_ajax_content' 
    // then, 
    my_function(); 
} 

load_ajax_content(); 
</script> 

好了,現在你的Ajax調用是同步的。您可以解析返回的HTML爲<script>標記,並分別處理它們,但它不漂亮:

function load_ajax_content() { 
    //...load and throw the first file into 'div_ajax_content' 
    // then grab the script nodes one-by-one 
    var scriptElts = document.getElementById('div_ajax_content').getElementsByTagName('script'), 
     scriptElt, 
     propName; // http://www.quirksmode.org/dom/w3c_html.html#t07 

    if (scriptElts.length) { 
     propName = scriptElts[0].textContent ? 'textContent' : 'innerText'; 
    } 

    for (var i=0; i<scriptElts.length; i++) { 
     scriptElt = document.createElement('script'); 
     scriptElt[propName] = scriptElts[i][propName]; 
     document.body.appendChild(scriptElt); 
    } 

    // finally, 
    my_function(); 
} 

...或者你可以只使用一個圖書館一樣jQuery,它自動地處理這個確切的問題(和許多其他!) 爲你。

+0

我剛剛修改了這個問題之前,您必須等待該調用完成。它同步加載 – jondinham

+1

@PaulDinh在你給出的例子中,你仍然在'load_ajax_content()'後面調用my_function(),而請求仍然是「在路上」。嘗試將my_function()調用移動到您的load_ajax_content函數的末尾,正如Matt所建議的那樣,它應該可以工作。 – GNi33

+0

@ GNi33它的同步 – jondinham

0

以下Kolink我發現了一個非常有趣的方法,但它的工作原理!

load_ajax_contents(); 
eval(document.getElementById("my_js_block").innerHTML); 
my_function(); 

然而,爲了使通過評估這些功能「的eval()」 全球,在第一個文件中的所有功能,必須聲明爲變量,就像這樣:

//this works! 
my_function = function() { 
    alert(9); 
} 

和沒有:

//this makes the function nested in the context where eval() is called 
function my_function() { 
    alert(9); 
} 

,也沒有:

//this makes the variable local to the context where eval() is called 
var my_function = function() { 
    alert(9); 
} 
相關問題