两次包含相同的JavaScript库有什么危险?

时间:2011-02-03 20:22:02

标签: javascript javascript-framework

我正在使用的其中一个webapp由许多部分HTML文件组成。如果partial需要一个JavaScript库,例如YUI,则YUI库包含在partial中。

当在运行时组合部分时,生成的HTML通常会多次包含YUI库。

<html>
... 
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
... 
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
... 
<script type="text/javascript" src="/js/yahoo/yahoo-min.js"></script>
...
</html>

我已经看过几次包含jQuery的奇怪行为,特别是在使用AJAX时。具体来说,为什么不止一次将同一个JavaScript库包含在一个坏主意中呢?为什么它有时只会引起问题?

4 个答案:

答案 0 :(得分:34)

根据库的不同,包括它可能会产生不良影响。

可以这样想,如果你有一个脚本将click事件绑定到一个按钮,并且你包含该脚本两次,那么当点击该按钮时,这些动作将被运行两次。

您可以编写一个简单的函数,您可以调用该函数来加载脚本并让它跟踪已加载的文件。或者,我确信您可以使用预先存在的JS加载程序(如LabJS)并对其进行修改。

答案 1 :(得分:10)

您应该采用我学习的方法来检查HTML5 Boilerplate的来源:

<script>
    !window.YAHOO && document.write(
        unescape('%3Cscript src="/js/yahoo/yahoo-min.js"%3E%3C/script%3E')
    );
</script>

我不使用YUI,因此将!window.YAHOO替换为全球YUI使用的任何内容。

如果库在全局范围内尚不存在,则此方法仅加载库。

答案 2 :(得分:6)

浏览器将缓存文件,只下载一次。然而,它将被执行多次。因此,性能影响可以忽略不计,但正确性影响可能不大。

答案 3 :(得分:2)

每次执行 。依赖于该文件,这可能是不合需要的。例如,如果文件包含alert("hello"),则每次引用文件时都会显示警告框,并且您可能希望它只显示一次。

编写安全库:

如果您只想要一次性执行,请按照以下方式解决问题。我们假设您正在编写一个库foobar.js,该库导出一个全局foobar

function foobar() {
 // ...
}

您可以使用以下代码确保文件的任何重复执行都变为no-ops:

window.foobar = window.foobar || function foobar() {
  // ...
};

使用不安全的库:

如果您无法修改图书馆的源代码,并且您已经确定它不安全,可以采用一种方法来解决它只加载一次图书馆的问题。创建一个全局并每次使用它来检查脚本是否已经加载。您必须自己将全局设置为真。

<script>(function() {
  if (! window.foobar) {
    var script = document.createElement('script');
    script.async = true; // remove this if you don't want the script to be async
    script.src = 'foobar.js';
    document.getElementsByTagName('head')[0].appendChild(script);
    window.foobar = true;
 }
}();</script>