如何让浏览器等待资源加载?

3
我正在使用JavaScript动态加载脚本和样式表,类似于这个的例子。
问题在于浏览器不会等待脚本加载完成。
假设我有一个名为functionToBeCalled()的函数,它在名为script-file.js的脚本文件中。
我有一个加载脚本文件的函数。
<script type="text/javascript">
   var listOfJavaScriptsLoaded = new Array();

    function LoadScriptFile(scriptUrl){
      var isScriptLoaded = false;
      var i = 0;
      for(i = 0; i < listOfJavaScriptsLoaded.length; i ++){
        if(listOfJavaScriptsLoaded[i] == scriptUrl){
           isScriptLoaded = true;
           break;
         }  
      } 
    if(isScriptLoaded == false){        
     var headTag= document.getElementsByTagName('head')[0];      
     var scriptTag= document.createElement('script');
     scriptTag.type= 'text/javascript';
     scriptTag.src= scriptUrl;
     headTag.appendChild(scriptTag);
     listOfJavaScriptsLoaded.push(scriptUrl);
    }
    }
   LoadScriptFile("script-file.js");
   functionToBeCalled();
</script>

现在的情况是当浏览器加载脚本标签时,它不等待该标签的加载而继续执行下一条命令。我收到了一个“undefined functionToBeCalled() ”错误。这是正常的。但事实是,当我在Firebug中检查时,脚本标签已经被形成并且文件已经加载。

那么,如何使浏览器在资产加载后暂停加载并恢复呢?

编辑1:此问题仅在通过ajax加载页面时出现,而不是在普通页面加载中出现

编辑2:是否有可能从JavaScript读取脚本/ CSS文件并将其直接写入标记内的脚本标签中?

如果使用window.stop(),则加载会完全停止。如何让它从同一行继续运行呢?

或者,是否可以使浏览器认为加载仍在进行中,并在onload事件中重置它?


1
为什么一开始要以这种方式加载它们?直接将它们放入head标签中或编写<script>标签绝对不是一个选项吗?这样会简单得多。 - Pekka
1
@ZX122R 是的。如果你将它写成正常的<script src='...'>标签放在页面主体中,页面加载将会等待脚本加载完成。 - Pekka
听听 Pekka 的话,因为他很聪明。 - Kyle
@ZX12R 不,我的意思是完全摆脱动态JS加载,改为使用<script src="script-file.js"></script>。我将我的答案更详细地阐述了这一点。 - Pekka
@pekka:抱歉我误解了。但是我会保留一个已加载脚本的数组,不会再次加载已经加载过的脚本。我该如何实现这个功能? - ZX12R
显示剩余6条评论
4个回答

3

您可能有特定的原因来动态加载脚本,但是为了提供这个选项,如果您在HTML输出中像下面这样编写脚本元素:

<script src="script-file.js"></script>
<script>functionToBeCalled();</script>

浏览器会停止解析,直到该脚本被加载和解释。

这也适用于在BODY中的有效


2

请查看Getify Solutions的LABjs(http://labjs.com/)。LABjs允许同时加载脚本插入的脚本,但按顺序运行。


这在 jQuery 中会失败吗? - ZX12R
根据labjs文档,它与jQuery 1.3存在一些不兼容性,但与1.4没有问题。 - Alohci
看起来是一个非常好的选择,除了我使用的许多插件还没有开始支持1.4版本。:( - ZX12R

0
几乎每个加载资源的标签都有一个onload事件。所以在纯JavaScript中,这意味着在您的情况下是这样的:
var s = document.createElement('script');
s.src = "script-file.js";
s.type = 'text/javascript';
head.appendChild(s);

s.onload = function(){
    functionToBeCalled();
}

如何在 onload 事件中告诉浏览器恢复加载其他元素? - ZX12R
@ZX12R 这将自动发生。然而,IE似乎不支持对脚本元素使用onload。请参见此处的解决方法:http://blog.andrewcantino.com/post/211671748/replacement-for-script-onload-in-ie - Pekka

0
我建议你看一下Cuzillion。它可以让你以多种不同的方式调用来观察它们在浏览器中的反应。
这应该能解答你的问题。只需在页面加载完成之前执行它即可。
<script type="text/javascript">
    var loadScriptFile = (function(){
        var listOfJavaScriptsLoaded = [];

        return function(scriptUrl){
            var isScriptLoaded = false;
            for(var i = 0; i < listOfJavaScriptsLoaded.length; i ++){
                if(listOfJavaScriptsLoaded[i] == scriptUrl){
                    isScriptLoaded = true;
                    break;
                }
            }
            if(!isScriptLoaded){
                document.write('<scr' + 'ipt type="text/javascript" src="' + scriptUrl + '"></scr' + 'ipt>');
            }
        };
    }());
    loadScriptFile("script-file.js");
    functionToBeCalled();
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接