如何将js文件包含到另一个js文件中,以便坚持DRY principle并避免重复代码。
答案 0 :(得分:244)
您只能在HTML页面中包含脚本文件,而不能在其他脚本文件中包含脚本文件。也就是说,你可以编写JavaScript,将你的“包含”脚本加载到同一页面中:
var imported = document.createElement('script');
imported.src = '/path/to/imported/script';
document.head.appendChild(imported);
您的代码很可能依赖于“包含”脚本,但在这种情况下,它可能会失败,因为浏览器将异步加载“导入”脚本。你最好的选择就是简单地使用像jQuery或YUI这样的第三方库,它可以解决这个问题。
// jQuery
$.getScript('/path/to/imported/script.js', function()
{
// script is now loaded and executed.
// put your dependent JS here.
});
答案 1 :(得分:16)
我不同意document.write
技术的批评者(见suggestion of Vahan Margaryan)。我喜欢document.getElementsByTagName('head')[0].appendChild(...)
的方式(参见suggestion of Matt Ball),但有一个重要问题:脚本执行的顺序包含在路上。我必须在下面更详细地描述问题。
最近我花了很多时间重现one close problem。众所周知的jQuery插件使用相同的技术(请参阅src here)来加载文件,但不同的人报告了处理这个问题的问题。我可以将问题描述如下。让我们拥有包含许多脚本的JavaScript库,并且loader.js
加载所有部分。部分中的一些来自另一部分。让我们为main.js
添加另一个<script>
脚本,该脚本在loader.js
之后立即使用loader.js
中的对象。问题是,有时main.js
在loader.js
加载的所有脚本之前执行。在$(document).ready(function () {/*code here*/});
脚本中使用main.js
也无济于事。 onload
中级联loader.js
事件处理程序的使用将遵循顺序而不是并行加载脚本,并且将难以使用main.js
脚本,该脚本应该仅包含在{{{1}之后的某处1}}。
我可以在我的环境中重现这个问题,并且可以看到在Internet Explorer 8中执行脚本的顺序可以是包含JavaScripts 的顺序。如果你需要包含一些依赖于另一个脚本的脚本,这是一个非常难的问题。问题在Loading Javascript files in parallel中有所描述。建议使用变通方法loader.js
:
document.writeln
描述了“脚本是并行下载但按照它们写入页面的顺序执行”的情况。从document.writeln("<script type='text/javascript' src='Script1.js'></script>");
document.writeln("<script type='text/javascript' src='Script2.js'></script>");
技术更改为document.getElementsByTagName('head')[0].appendChild(...)
后,我从未见过任何问题。
所以我建议您使用document.writeln
。
更新:如果某人有兴趣,可以尝试在Internet Explorer中加载(并重新加载)the page(页面使用document.writeln
技术)并与{{进行比较3}}使用了document.getElementsByTagName('head')[0].appendChild(...)
。 (页面的代码相对较脏,不是来自我,但它可以用来重现我描述的问题。)
答案 2 :(得分:5)
不可能直接。你也可以编写一些可以处理它的预处理器。
如果我理解正确,那么以下是有助于实现这一目标的事情:
使用将运行JS文件的预处理器,例如查找“@import somefile.js”等模式,并将其替换为实际文件的内容。 Nicholas Zakas(雅虎)用Java编写了一个这样的库,你可以使用它(http://www.nczonline.net/blog/2009/09/22/introducing-combiner-a-javascriptcss-concatenation-tool/)
如果您正在使用Ruby on Rails,那么您可以尝试使用Jammit资产包装,它使用assets.yml配置文件,您可以在其中定义可包含多个文件的包,然后在您的实际网页中引用它们包名。
JavaScript目前不提供将CSS文件包含在CSS(@import)之类的另一种“本机”方式,但所有上述工具/方法都有助于实现您提到的DRY原则。我可以理解,如果你来自服务器端背景,它可能不会直观,但事情就是这样。对于前端开发人员来说,这个问题通常是“部署和打包问题”。
希望它有所帮助。
答案 3 :(得分:4)
你需要这么写
document.write('<scr'+'ipt type="text/javascript" src="other js file.js" ></scr'+'ipt>');
在你的第一个js文件中