加载 JavaScript 文件时是否会触发事件?问题出现是因为 YSlow 建议将 JavaScript 文件移动到页面底部。这意味着
$(document).ready(function1)
在function1
加载包含代码的 js 文件之前触发。
如何避免这种情况?
加载 JavaScript 文件时是否会触发事件?问题出现是因为 YSlow 建议将 JavaScript 文件移动到页面底部。这意味着
$(document).ready(function1)
在function1
加载包含代码的 js 文件之前触发。
如何避免这种情况?
我没有方便的参考,但是脚本标签是按顺序处理的,所以如果你把你$(document).ready(function1)
的脚本标签放在定义函数1等的脚本标签之后,你应该很高兴。
<script type='text/javascript' src='...'></script>
<script type='text/javascript' src='...'></script>
<script type='text/javascript'>
$(document).ready(function1);
</script>
当然,另一种方法是通过组合文件作为构建过程的一部分来确保您总共只使用一个脚本标记。(除非你从某个地方的 CDN 加载其他的。)这也将有助于提高页面的感知速度。
编辑:刚刚意识到我实际上并没有回答您的问题:我认为没有触发跨浏览器事件,不。 如果您足够努力,请参见下文。您可以测试符号并使用 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% 跨浏览器可靠的。另请注意,某些浏览器会同时执行这两种机制,因此该done
变量可以避免重复通知。
当他们说“页面底部”时,他们的意思并不是字面上的底部:他们的意思是在结束</body>
标记之前。将脚本放在那里,它们将在 DOMReady 事件之前加载;之后放置它们,DOM 将在加载它们之前准备好(因为在</html>
解析结束标记时它已经完成),正如您发现的那样,这将不起作用。
如果你想知道我怎么知道这就是他们的意思:我曾在雅虎工作过!我们把我们的脚本放在</body>
标签之前:-)
编辑:另外,请参阅 TJ Crowder 的回复并确保您按正确的顺序排列。
看看 jQuery 的 .load() http://api.jquery.com/load-event/
$('script').load(function () { });
除了@TJ Crowder 的回答之外,我还添加了一个递归外循环,允许遍历数组中的所有脚本,然后在加载所有脚本后执行一个函数:
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 Crowder - 我对我在其他线程中看到的“在运行回调之前添加几秒钟的延迟”感到畏缩。
我总是从 JavaScript 文件的末尾调用来注册它的加载,它曾经对我来说非常适合所有浏览器。
例如:我有一个 index.htm、Js1.js 和 Js2.js。我在 index.htm 标头中添加了函数 IAmReady(Id) 并使用文件末尾的参数 1 和 2 调用它,分别是 Js1 和 Js2。一旦 IAmReady 函数从两个 js 文件中获得两次调用(将调用次数存储在静态/全局变量中),它就会有一个运行启动代码的逻辑。