【问题标题】:Best way to signal my JS script is loaded表明我的 JS 脚本已加载的最佳方式
【发布时间】:2010-10-09 14:52:13
【问题描述】:

我有一个 JS 脚本,它将托管在我的服务器上,其他人将嵌入到他们的 html 中,即

...<code for http://yoursite.example.com />
<script type="text/javascript" src="http://mysite.example.com/awesome.js" />
...<code for http://yoursite.example.com />

我的脚本声明了一个对象,其中包含许多可用作 Javascript Object() 的属性,即

<script type="text/javascript">
//From http://mysite.example.com/awesome.js
alert(Awesome.Name);
</script>

由于加载时间的差异,我似乎需要表明我的脚本中的“Awesome”对象已准备就绪。我需要它独立存在,因此不依赖于特定的 JS 框架。

我是否需要发布我自己的自定义 JS 事件,或者我的脚本已加载这一简单事实是否被现有页面级事件之一捕获?我应该怎么做?

更新:作为参考,如果我将 JS 包含在从 http://mysite.example.com 运行的 HTML 页面中,则 Awesome 对象可用并已填充。当 JS 文件包含在另一个域中时,该对象在运行时未定义。

【问题讨论】:

  • 抱歉,选词。出版?发射?宣布?火灾?不确定在这种情况下合适的白话是什么——javascript不是我的正常开发领域。

标签: javascript dom-events unobtrusive-javascript


【解决方案1】:

&lt;script&gt;标签的javascript内容是按程序执行的,所以这个

<script type="text/javascript" src="http://mysite.com/awesome.js" />
<script type="text/javascript">
    alert(Awesome.Name);
</script>

如果在任何 previous 脚本标记中找到,只会提醒 Awesome.Name 的内容。

要了解页面上的所有内容是否已完全加载,您必须使用 DOMContentLoaded(对于 firefox)和“onreadystatechange”(对于 ie)。如果您不关心检查 DOM,您也可以简单地检查 window 对象上的 load 事件(可能更容易)。

if ( document.addEventListener ) {
    document.addEventListener( "DOMContentLoaded", function(){
         doSomething();   
    }, false );
} else if ( document.attachEvent ) { // IE        
    document.attachEvent("onreadystatechange", function(){
        if ( document.readyState === "complete" ) {
            doSomething();
        }
    });
}

【讨论】:

  • 啊,很好,DOMContentLoaded。那么,IE、Safari、Opera 的简单答案是什么? ;-)
  • @jro:如果您可以等待图像加载,请使用window.onload;您还可以将脚本作为最后一个元素添加到body;如果您不希望前者的延迟/不喜欢后者,请自己使用框架或实施变通方法(doScroll、defer、onreadystatechange、...)
  • @Luca:只添加一个'onreadystatechange'监听器是不够的:你必须检查readyState的值,否则即使文档仍然不完整,你的函数也可能会被执行!
  • @Luca: 是的,跨平台事件处理很麻烦 :( 顺便说一句:在 IE 中的 afaik,document.readyState = complete 在外部资源加载后触发,即没有比 window.onload除了事件直接在onload 侦听器之前触发...
  • @Luca:你把readyState-check 放得太高了一级:它必须在监听器内部
【解决方案2】:

如果您的脚本需要在实例化对象之前加载 DOM,您应该查看一些框架并了解它们如何处理此问题,然后在您的代码中实现它。如果您不需要加载 DOM,那么我会让用户根据加载时间担心使用对象的时间。通常,一旦您的脚本被加载,您的对象应该可以使用,这意味着该对象应该在包含它的 script 标记之后立即可用。

【讨论】:

  • 谢谢。 “一旦加载脚本,您的对象应该可以使用”是我的理解,但我没有看到这种行为。完全填充/声明对象存在延迟。
【解决方案3】:

可以通过window 范围访问全局范围内可访问的任何内容。因此,您可以使用这个:

if (window["Awesome"] != null) { /* do something */ }

【讨论】:

    【解决方案4】:

    A)。你意识到脚本请求被阻塞了吗?您对此满意还是想解决这个问题,因为您的问题的答案取决于它。

    B)。赤裸裸的防弹机制和简单的机制是调用可以保证页面上存在的指定方法。让该方法的实现由用户来做。存在许多其他方法,但我们需要知道您的代码的生命周期和意图究竟是什么来推荐任何东西。

    【讨论】:

    • 谢谢。不,不知道脚本请求被阻止。我不确定我是否遵循您的建议,所以任何帮助都很棒。您是否建议我的库(由具有属性的对象组成)调用页面上的方法?它只是一个数据容器,供其他对象访问。
    【解决方案5】:

    你可以像这样简单地使用它:

    <script type="text/javascript" src="myfunction.js"></script>
    <script type="text/javascript" src="iwannaloadthis.js?onload=executeThis"></script>
    

    记住如前所述,执行 this 必须在 myfunction.js 中定义(或在尝试加载 iwannaloadthis.js 之前。

    希望这会有所帮助!

    【讨论】:

    • 谢谢,但您错过了一个关键要求:“我需要它独立存在,因此不依赖于特定的 JS 框架。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2010-10-04
    • 1970-01-01
    • 2016-09-08
    相关资源
    最近更新 更多