简体   繁体   English

等待动态加载的Javascript文件完成加载的有效方法是什么?

[英]What is an efficient way of waiting for a dynamically loaded Javascript file to finish loading?

I'm loading a Javascript file that has a function in it that I'd like to call. 我正在加载一个Javascript文件,其中包含我要调用的功能。 This is not possible, since between 'initiating' the load, and actually calling the function, the JS isn't loaded yet. 这是不可能的,因为在“启动”加载和实际调用函数之间,尚未加载JS。 Of course, I could do something like setTimeout('functionCall();',5000); 当然,我可以做类似setTimeout('functionCall();',5000);事情setTimeout('functionCall();',5000); , but I don't think this is a very efficient method, and it seems really unstable to me. ,但我认为这不是一种非常有效的方法,对我来说似乎真的很不稳定。 That's why I was wondering whether there was a better way to do it. 这就是为什么我想知道是否有更好的方法来做到这一点。

Here's the code I'm using. 这是我正在使用的代码。 The function in question is called controllerStart . 有问题的函数称为controllerStart If I comment out the last line here, and type it into a Javascript terminal (like on Chrome developer tools), everything works. 如果我在这里注释掉最后一行,然后将其键入Javascript终端(例如在Chrome开发人员工具上),则一切正常。

    function loadController(name){
        clearAll();
        scriptContainer.innerHTML = '';
        var scriptElement = document.createElement('script');
        scriptElement.setAttribute('src','controllers/' + name + '.js');
        scriptElement.setAttribute('type','text/javascript');
        scriptContainer.appendChild(scriptElement);
        controllerStart();// <-- Doesn't work from here, but works on a terminal
    }

Thanks for taking a look! 谢谢参观!

call the function after you reference the Javascript. 引用Javascript后,调用该函数。

JS loading is SYNCHRONOUS. JS加载是同步的。

So..... 所以.....

---- js library call ----- ---- js库调用-----

----- call the function here ----- -----在这里调用函数-----

Profit! 利润!

edit: specifically : 编辑:专门:

function loadController(name){
        clearAll();
        scriptContainer.innerHTML = '';
        var scriptElement = document.createElement('script');
        scriptElement.setAttribute('src','controllers/' + name + '.js');
        scriptElement.setAttribute('type','text/javascript');
        scriptContainer.appendChild(scriptElement);
        scriptElement.onload = new function(){controllerStart();}; 
       //something like that.
    }

edit 2: my bad - use "onload" not "load" - too much jquery on the brain 编辑2:我不好-使用“ onload”而不是“ load”-大脑上的jQuery过多

more about "onload" here: http://www.onlinetools.org/articles/unobtrusivejavascript/chapter4.html 有关“加载”的更多信息,请访问: http : //www.onlinetools.org/articles/unobtrusivejavascript/chapter4.html

There is a good post from Nicholas C. Zackas about it which you can read here , that includes just the code you want to use. Nicholas C. Zackas有一篇很好的文章,您可以在这里阅读,其中仅包含您要使用的代码。

Basically it's just a function that includes both a URL of a JS file to load, and a callback to execute when it's been loaded. 基本上,它只是一个函数,其中包含要加载的JS文件的URL和要在加载时执行的回调。 It then creates the <script> tag, attaches the callback to execute after it's loaded (via the onreadystatechange or the onload event) and inserts it into the DOM. 然后,它创建<script>标记,在回调加载后(通过onreadystatechange或onload事件)附加要执行的回调,并将其插入DOM。

Then, all you need to do is call it like: 然后,您需要做的就是这样调用它:

loadScript('controllers/' + name + '.js', controllerStart);

From the sound of it you're loading your JavaScript asynchronously. 从它的声音来看,您正在异步加载JavaScript。 In more recent browsers there's an onload event on the tag which fires when it's finished loading. 在最近的浏览器中,标记上有一个onload事件,当事件加载完成时会触发该事件。 But if you need cross-browser support, the only way to do it is to either: 但是,如果您需要跨浏览器支持,则唯一的方法是:

(a) if it's loaded from the same server as your page, load your javascript using AJAX and then execute it with eval() when it's loaded (instead of using <script> tags), (a)如果它是从与您页面相同的服务器上加载的,请使用AJAX加载javascript,然后在加载时使用eval()执行它(而不是使用<script>标记),

(b) if you control the file add an event trigger to the end of it which you then listen for in your main JavaScript file. (b)如果您控制该文件,则在其末尾添加一个事件触发器,然后在主JavaScript文件中进行监听。 JQuery's bind() and trigger() functions are handy for that. jQuery的bind()和trigger()函数非常方便。

(c) if it's loaded from somewhere else and you don't control it (but do have permission to redistribute it), relocate it to your server and follow (a). (c)如果它是从其他地方加载的,并且您没有控制权(但确实具有重新分发的许可),请将其重新放置到服务器上并遵循(a)。

You also could do away with asynchronous loading and just put a stream of <script> tags in your header, the old fashioned way. 您也可以取消异步加载,只需在标头中放一个<script>标记流即可,这是一种老式的方法。 That guarantees that each script won't be run until after the previous script has finished. 这样可以保证每个脚本直到上一个脚本完成后才能运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM