我正在使用的其中一个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库包含在一个坏主意中呢?为什么它有时只会引起问题?
答案 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>