document.write,onload和变量范围问题

时间:2012-01-13 07:46:03

标签: javascript 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就像这样=&gt;

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

和a2.js非常相似=&gt;

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

我希望最后一个控制台输出等于2,但这是我从控制台输出的内容=&gt;

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

我猜这个问题与范围有关,但我无法弄清楚如何。

如果你们中的任何人知道这里发生了什么,那就太好了。

3 个答案:

答案 0 :(得分: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>

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

尝试一下。

我得到的输出

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)

答案 2 :(得分:0)

我怀疑onA1Ready()被称为onLoad,它写了另一个被调用onLoad的函数,因为文档已经被加载,所以它永远不会被调用。

相关问题