为什么浏览器不解析AJAX加载的文件中的JS代码?

时间:2011-11-16 00:47:03

标签: php javascript html ajax xmlhttprequest

我有2个文件,第一个文件有一些HTML和一部分JS。第二个文件是主文件,它通过'XmlHttpRequest。

加载第一个文件

第一个文件是这样的:

<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>

如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

Ajax是异步的。您的代码会在my_function()完成之前尝试致电XMLHttpRequest。这样做:

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

load_ajax_content();
</script>

好的,现在你的ajax调用是同步的。您可以为<script>标记解析返回的HTML,并单独处理它们,但它并不漂亮:

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这样的库,它可以自动处理这个问题(以及许多其他问题!)。

答案 1 :(得分:3)

通过innerHTML添加脚本不会运行脚本。因此,您的功能未被定义,因此失败。

相反,我建议单独加载HTML和JS,并使用DOM方法附加JS以在页面上放置<script>标记,或者eval()来执行返回的文件内容。

答案 2 :(得分: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);
}