如何检测是否加载了javascript文件?

时间:2009-08-18 11:47:57

标签: javascript jquery

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

如何避免这种情况?

7 个答案:

答案 0 :(得分:67)

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

<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变量可以避免重复通知。

答案 1 :(得分:5)

当他们说“页面底部”时,他们并不代表底部:他们的意思是在结束</body>标签之前。将脚本放在那里,它们将在DOMReady事件之前加载;之后放置它们并且DOM在它们被加载之前就已准备就绪(因为它在解析结束</html>标记时已经完成),你发现它将不起作用。

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

编辑:另见T.J.克劳德的回复,并确保你有正确的顺序。

答案 2 :(得分:5)

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

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

答案 3 :(得分:2)

我总是从JavaScript文件的末尾开始调用它来注册它的加载,它曾经适用于所有浏览器。

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

答案 4 :(得分:1)

继续@ T.J。 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();
            }
        })
    }
}

当然你可以制作一个包装来摆脱&#39; 0&#39;如果你愿意:

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

很棒的工作@ T.J。克劳德 - 我正在努力,只需在运行回调之前加上几秒钟的延迟即可。我在其他帖子中看到了。

答案 5 :(得分:0)

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

另外,我总是发现将ready回调定义为匿名方法然后命名为1更好。

答案 6 :(得分:0)

像T.J. wrote:订单定义的(至少它是顺序的,当您的浏览器是关于执行任何JavaScript时,即使它可能以某种方式并行下载脚本) 。但是,显然你遇到了麻烦,也许你正在使用第三方JavaScript库产生404 Not Found或超时?如果是,请阅读Best way to use Google’s hosted jQuery, but fall back to my hosted library on Google fail.