2011-01-08 134 views
157

可能重複:
Including a .js file within a .js file如何在其他js文件中包含js文件?

我怎麼能包括的js文件到另一個js文件,這樣才能堅持DRY principle和避免重複代碼。

+2

[在.js文件中包含.js文件]的可能重複(http://stackoverflow.com/questions/2145914/including-a-js-file-within-a-js-file)或[this一個](http://stackoverflow.com/questions/950087/include-javascript-file-inside-javascript-file) – user113716 2011-01-08 15:47:30

回答

187

寫了這麼

document.write('<scr'+'ipt type="text/javascript" src="other js file.js" ></scr'+'ipt>'); 

您只能包含在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. 
}); 
4

這是不可能的。你可以寫一些可以處理的預處理器。

如果我沒有理解它正確然後在下面是東西,可以幫助實現這一目標:

  • 使用預處理器將通過您的JS文件運行例如尋找像「@import模式somefile.js「並將其替換爲實際文件的內容。尼古拉斯Zakas(雅虎)在Java中寫一個這樣的庫,你可以如果您正在使用Ruby on Rails的,那麼你可以給Jammit資產打包嘗試使用(http://www.nczonline.net/blog/2009/09/22/introducing-combiner-a-javascriptcss-concatenation-tool/

  • ,它採用assets.yml配置文件,您可以定義可以包含多個文件的軟件包,然後通過軟件包名稱在實際網頁中引用它們。

  • 嘗試使用像RequireJS這樣的模塊加載器或像LabJs這樣的腳本加載器來控制加載順序以及利用並行下載。

的JavaScript目前不提供包括JavaScript文件到另一個像CSS(@import)的「原生」的方式,但所有以上提到的工具/方法可以幫助實現你所提到的DRY原則。我可以理解,如果你來自服務器端的背景,它可能不會感覺到直覺,但事情是這樣的。對於前端開發人員來說,這個問題通常是「部署和打包問題」。

希望它有幫助。

+0

你能舉個例子嗎? – 2011-01-08 15:46:50

+0

我編輯了我的答案,以更好地解釋我的想法。希望這一次我清楚了。 – Arnab 2011-01-08 16:01:39

0

你需要在你的第一個js文件

+12

呃,請不要**提倡使用`document.write()`。 – 2011-01-08 15:49:56

10

我不同意document.write技術(參見suggestion of Vahan Margaryan)的評論家。我喜歡document.getElementsByTagName('head')[0].appendChild(...)(見suggestion of Matt Ball)的方式,但是有一個重要的問題:這個腳本包含的腳本執行順序是。我必須在下面更詳細地描述這個問題。

最近我花了很多時間重現one close problem。衆所周知,jQuery插件使用相同的技術(請參見src here)來加載文件,但不同的人報告了這個問題。我可以將問題描述如下。讓我們來創建一個由多個腳本組成的JavaScript庫,其中一個加載所有零件。一部分來自另一部分。讓我們包含另一個main.js腳本,每<script>使用來自loader.js之後的loader.js之後的對象。問題是有時候,main.jsloader.js加載的所有腳本之前執行。使用$(document).ready(function() {/*code here*/});裏面的main.js腳本也無濟於事。在loader.js中級聯onload事件處理程序的使用將遵循順序而不是並行加載腳本,並將難以使用main.js腳本,該腳本應該僅包括在loader.js之後的某處。

我可以在我的環境中重現問題,並且可以看到在Internet Explorer 8中執行腳本的順序可以是另一個順序,包括JavaScript。如果你需要包含一些依賴另一個腳本的腳本,這是非常困難的問題。該問題在Loading Javascript files in parallel中描述。作爲解決辦法是建議使用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後,我從來沒有看到任何問題更多。因此我建議您使用document.writeln

修訂:如果有人有在Internet Explorer(頁面使用document.getElementsByTagName('head')[0].appendChild(...)技術)的興趣,他可以嘗試加載(和重裝)the page和比較the fixed version使用document.writeln。 (該頁面的代碼相對較髒,不是來自我的,但它可以用來重現我所描述的問題)。