如何在加载之前避免丢失对外部JS文件的调用

时间:2011-01-08 19:26:26

标签: javascript object

我的问题是,多个网站将包含我的JS文件,并且在调用这样的内容时:

<script src="..."></script>

hello.say("yay");

会出现种族问题,所以有时它可能会导致种族问题。我知道我可以通过将每个函数放在window.onload中来轻松解决这个问题,但这不会很干净,因为我看到其他网站像谷歌分析一样神奇地解决了这个问题:

.. Calling google analytics JS..

<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-xxxxxx-x");     <-- this an object !
pageTracker._trackPageview();
} catch(err) {}
</script>

怎么做?

4 个答案:

答案 0 :(得分:4)

Google Analytics使用的技巧是一个完美的例子,只能在鸭子类型的语言中完成。如果GA脚本没有加载,则主要对象是一个数组,但如果它有更改行为。让我们看看我是否可以解释它。

我在stackoverflow上从源代码中提取了这篇文章:

var _gaq = _gaq || [];
_gaq.push(['_setAccount','UA-5620270-1']);
_gaq.push(['_trackPageview']);

它看起来像一个数组,其中有一些值被推送到它。实际上,如果_gaq在运行此代码时为falsy(因为如果没有其他分析 - JavaScript已经运行),则将其作为数组。然后,当主分析脚本(包含在页面上任何位置的脚本标记)加载时,它会检查此数组并根据数组的内容执行某些任务。

因此,如果这种情况以相反的顺序发生(首先加载主脚本,然后加载上面的代码片段)主脚本将_gaq设置为一个对象,其推送方法可以执行谷歌希望它执行的任何操作。稍后,当上面的代码运行时,_gaq.push不只是向数组添加值;它实际上执行任意代码(并且根本不会推送到数组)。

因此,无论哪个脚本首先运行,最终结果都是相同的。

答案 1 :(得分:0)

如果您将文件包含在html页面的标题部分中,则会在页面中的任何其他javascript运行之前加载它。

UPD:另外,我认为即使是在处理其余的javascripts之前,也会下载thml文本中包含的文件。你确定这首先是你的问题吗?

答案 2 :(得分:0)

在页面完全加载之前,您需要延迟执行依赖于外部javascript的任何javascript代码,并且可以通过将执行附加到window.onload事件来执行此操作。

window.onload = function() {
  hello.say('yay');
}

但是这样做的缺点是只能处理一个函数,并且会覆盖最初附加到该事件的任何函数。您可能希望阅读Simon Wilson的帖子以及有关如何处理这种情况的解决方案的评论。

http://simonwillison.net/2004/May/26/addLoadEvent/

答案 3 :(得分:0)

我对你认为种族问题在这里有点不确定。

浏览器总是*按照他们看到的顺序执行脚本标记。如果不是这样,互联网的很大一部分就会破裂 - 以及现有的几乎所有常见的JavaScript库。

因此,只要用户在文档中加载脚本比在调用API时加载脚本,就应该没有问题。我能想到的唯一可能的例外是你的脚本的初始化依赖于异步逻辑,在这种情况下你应该考虑为用户提供自己的标准回调机制来编写代码。

如果用户可能会在他们使用API​​之后加载您的脚本,那么Jakob在他的回答中提到的技巧就可以了。但我甚至不确定你的目标是那么复杂。

*编辑:我应该注意,说实话,有一些特定的例外情况,但只要你只是处理HTML文档中<script>标签的标准非延迟使用。