如何控制Javascript执行顺序?

时间:2009-04-02 05:49:53

标签: javascript html cross-browser

我正在构建一个网页的并发问题。基本上,我有三个脚本文件,我用来保存一些数据:

script1.js:

var myValue = 1;

script2.js:

var myValue = 2;

script3.js:

var myValue = 3;

我有一个页面, mypage.html 基本上看起来像这样:

<html>
<script>
   function get_number()
   {
     var script_file = GetQueryStringValue( "run" );
     e = document.createElement('script');
     e.type='text/javascript';
     e.src = script_file + ".js"
     head.appendChild( e );

     document.write( myValue );
   }
</script>
<body onload="get_number()">
   <div onclick="get_number()">Click me!</div>
</body>
</html>

此页面的主要想法是您可以像这样查询:     mypage.html?run=script1 这将告诉get_number()函数动态插入script1.js到mypage.htm。然后,我调用get_number()来显示从脚本加载的值。

现在,我已经将上述内容简化为我认为的相关部分,显然我遗漏了很多东西。我的实际代码加载了大量的值并且更有趣......但是,我希望有人可以帮助我解决这个问题。

我发现在IE中,数字显示正确。

在Firefox,Chrome和Safari中,我收到myValue未定义的错误。但是,如果单击我创建的Click me div,则数字会正确显示。所以,我知道我正在加载javascript外部文件。但是,我的get_number()功能无法正常加载onload

现在,我稍微修改了我的文件,以便get_number函数看起来像这样:

 function get_number()
 {
   var script_file = GetQueryStringValue( "run" );
   e = document.createElement('script');
   e.type='text/javascript';
   e.src = script_file + ".js"
   head.appendChild( e );

   setTimeout( function() { document.write( myValue ), 10 } );
 }

setTimeout延迟了足够的时间来更新DOM,并且在大多数情况下都会加载javascript。但是,这完全是黑客攻击。 Firefox倾向于一直正确地加载这个“改进的”代码,而Chrome和Safari设法在大约50%的时间内获得该值。

所以,我想我想知道,有没有更好的方法来完成我在这里尝试做的事情?从外部驱动值(通过查询字符串)非常重要,但除了该要求之外,我非常灵活。

2 个答案:

答案 0 :(得分:6)

使用head.appendChild等DOM方法动态加载脚本文件的方法是异步的,这意味着在运行任何其他代码之前页面不会等待它加载。如果您不想要这种异步行为,可以在HTML中使用常规元素加载它们,或者您可以使用“同步”XMLHttpRequest来抓取它并使用eval()来运行它。

但是,您可能不希望这样做,因为无论如何,异步会使整个页面加载速度更快。在继续下一段代码之前,您可能只需要添加一些等待动态加载的脚本加载的逻辑。但是,这可能涉及使用setInterval()进行轮询,直到您发现已定义包含的脚本中的变量为止。或者,您可以在包含的脚本中添加代码,该代码将方法调用到等待它的任何内容。

或者,你可以看看jQuery是如何做类似的事情,寻找定义ajax方法的地方,特别是这些部分......

var script = document.createElement("script");

// then later ...

script.onload = script.onreadystatechange = function(){
    if ( !done && (!this.readyState ||
    this.readyState == "loaded" || this.readyState == "complete") ) {

        // do processing
            head.removeChild( script );
    }
};

// ...

head.appendChild(script);

答案 1 :(得分:3)

你是否可以为你的脚本文件添加一个函数调用,这样当它们运行时,它们会调用你的函数

document.write( myValue );

这样script1.js就是

var myValue = 1;
scriptLoaded();

并且您的主文件将包含:

function scriptLoaded(){
   document.write( myValue );
}