如何检测JavaScript文件是否加载?

JavaScript文件加载时是否有事件触发? 问题出现了,因为YSlowbuild议将JavaScript文件移动到页面底部。 这意味着$(document).ready(function1)在包含function1代码的js文件被加载之前触发。

如何避免这种情况?

我没有参考它的方便,但脚本标签按顺序处理,所以如果你把你的$(document).ready(function1)放在脚本标签后面的脚本标签定义function1等,你应该很好走。

 <script type='text/javascript' src='...'></script> <script type='text/javascript' src='...'></script> <script type='text/javascript'> $(document).ready(function1); </script> 

当然,另一种方法是通过将文件合并为构build过程的一部分来确保您只使用一个脚本标记。 (除非你从其他地方加载CDN中的其他文件)。这也有助于提高网页的感知速度。

编辑:只是意识到,我没有真正回答你的问题: 我不认为有一个跨浏览器的事件被解雇,没有。 如果你努力工作,请看下面。 您可以testing符号并使用setTimeout来重新安排时间:

 <script type='text/javascript'> function fireWhenReady() { if (typeof function1 != 'undefined') { function1(); } else { setTimeout(fireWhenReady, 100); } } $(document).ready(fireWhenReady); </script> 

…但是,如果您的脚本标记顺序正确,则不必这样做。


更新:如果你喜欢,你可以获得加载到页面的script元素的加载通知。 为了获得广泛的浏览器支持,你必须做两件不同的事情,但作为一种组合的技术,它可以工作:

 function loadScript(path, callback) { var done = false; var scr = document.createElement('script'); scr.onload = handleLoad; scr.onreadystatechange = handleReadyStateChange; scr.onerror = handleError; scr.src = path; document.body.appendChild(scr); function handleLoad() { if (!done) { done = true; callback(path, "ok"); } } function handleReadyStateChange() { var state; if (!done) { state = scr.readyState; if (state === "complete") { handleLoad(); } } } function handleError() { if (!done) { done = true; callback(path, "error"); } } } 

根据我的经验,错误通知( onerror )不是100%跨浏览器可靠的。 另外请注意,一些浏览器将执行这两种机制,因此donevariables,以避免重复的通知。

当他们说“页面底部”时,它们并不意味着底部:它们就是在closures</body>标签之前。 将您的脚本放在那里,它们将在DOMReady事件之前加载; 之后放置它们,DOM将在加载之前准备好(因为在parsing结束</html>标记时它是完整的),正如你find的那样,它将不起作用。

如果你想知道我是如何知道这是他们的意思:我曾在雅虎工作过。 我们把脚本放在</body>标记之前:-)

编辑:另外,请参阅TJ克劳德的答复,并确保你有正确的顺序的东西。

看看jQuery的.load() http://api.jquery.com/load-event/

 $('script').load(function () { }); 

我总是从JavaScript文件的末尾打一个电话来注册它的加载,这对我来说适用于所有的浏览器。

例如:我有一个index.htm,Js1.js和Js2.js。 我在index.htm头文件中添加了函数IAmReady(Id),并分别从文件末尾的参数1和2中调用Js1和Js2。 一旦IAmReady函数从两个js文件获得两个调用(将调用的数目存储在一个静态/全局variables中),IAmReady函数将具有运行启动代码的逻辑。

除了@TJ Crowder的回答,我已经添加了一个recursion的外部循环,允许一个循环遍历数组中的所有脚本,然后在所有脚本加载后执行一个函数:

 loadList([array of scripts], 0, function(){// do your post-scriptload stuff}) function loadList(list, i, callback) { { loadScript(list[i], function() { if(i < list.length-1) { loadList(list, i+1, callback); } else { callback(); } }) } } 

当然,如果你喜欢,你可以做一个包装来摆脱'0'

 function prettyLoadList(list, callback) { loadList(list, 0, callback); } 

不错的工作@TJ克劳德 – 我刚刚在'只是在运行callback之前加了几秒钟',我在其他线程看到。

更改脚本的加载顺序,以便在使用readycallback之前定义function1

另外,我总是发现最好将readycallback定义为匿名方法,然后命名为one。

像TJ 写道 :定义的顺序(至less它是连续的,当你的浏览器即将执行任何JavaScript,即使它可能以某种方式并行下载脚本)。 但是,显然你遇到了麻烦,也许你正在使用第三方的JavaScript库产生一些404未find或超时? 如果是这样,那么请阅读使用Google托pipe的jQuery的最佳方式,但是退回到我在Google上的托pipe库失败。