2011-01-08 57 views
157

thể trùng lặp:
Including a .js file within a .js fileLàm cách nào để đưa tệp js vào tệp js khác?

Làm thế nào tôi có thể bao gồm một file js vào một tập tin js, để dính vào DRY principle và tránh trùng lặp mã.

+2

bản sao có thể có của [Bao gồm tệp .js trong tệp .js] (http://stackoverflow.com/questions/2145914/including-a-js-file-within-a-js-file) hoặc [this một] (http://stackoverflow.com/questions/950087/include-javascript-file-inside-javascript-file) – user113716

Trả lời

187

Bạn chỉ có thể bao gồm một tập tin kịch bản trong một trang HTML, không phải trong một file script. Điều đó nói rằng, bạn thể viết JavaScript mà tải bạn "bao gồm" kịch bản vào cùng một trang:

var imported = document.createElement('script'); 
imported.src = '/path/to/imported/script'; 
document.head.appendChild(imported); 

Có một cơ hội tốt mã của bạn phụ thuộc vào bạn "bao gồm" kịch bản, tuy nhiên, trong trường hợp này nó có thể thất bại vì trình duyệt sẽ tải tập lệnh "đã nhập" không đồng bộ. Đặt cược tốt nhất của bạn sẽ đơn giản là sử dụng thư viện của bên thứ ba như jQuery hoặc YUI, giải quyết vấn đề này cho bạn.

// jQuery 
$.getScript('/path/to/imported/script.js', function() 
{ 
    // script is now loaded and executed. 
    // put your dependent JS here. 
}); 
+3

Tôi chỉ có thể lặp lại: trong trường hợp sử dụng '$ .getScript', tập lệnh phụ thứ hai sẽ được bắt đầu tải ** sau khi tập lệnh đầu tiên được tải và thực thi **. Nó là ** tuần tự thay vì tải song song **. Hơn nữa, nếu ai đó bao gồm một tập tin 'loader.js' như'

4

Không thể trực tiếp. Bạn cũng có thể viết một số tiền xử lý mà có thể xử lý đó.

Nếu tôi hiểu đúng thì dưới đây là những điều mà có thể hữu ích để đạt được điều đó:

  • Sử dụng một bộ xử lý trước đó sẽ chạy qua các file JS của bạn ví dụ như tìm kiếm các mẫu như "@import somefile.js "và thay thế chúng bằng nội dung của tệp thực. Nicholas Zakas (Yahoo) đã viết một thư viện như vậy trong Java mà bạn có thể sử dụng (http://www.nczonline.net/blog/2009/09/22/introducing-combiner-a-javascriptcss-concatenation-tool/)

  • Nếu bạn đang sử dụng Ruby on Rails thì bạn có thể dùng thử tài sản Jammit, nó sử dụng tệp cấu hình assets.yml nơi bạn có thể xác định các gói của bạn có thể chứa nhiều tệp và sau đó tham chiếu chúng trong trang web thực của bạn theo tên gói.

  • Hãy thử sử dụng bộ nạp mô-đun như RequireJS hoặc trình tải tập lệnh như LabJs với khả năng kiểm soát chuỗi tải cũng như tận dụng tải xuống song song.

JavaScript hiện không cung cấp cách "nguyên bản" bao gồm tệp JavaScript vào CSS khác như @import, có thể hữu ích để đạt được nguyên tắc DRY bạn đã đề cập. Tôi có thể hiểu rằng nó có thể không cảm thấy trực quan nếu bạn đến từ một nền tảng phía máy chủ nhưng đây là cách mọi thứ. Đối với các nhà phát triển front-end vấn đề này thường là một "vấn đề triển khai và đóng gói".

Hy vọng điều đó sẽ hữu ích.

+0

bạn có thể đưa ra ví dụ không? –

+0

Tôi đã chỉnh sửa câu trả lời của mình để giải thích rõ hơn suy nghĩ của tôi. Hy vọng lần này tôi đủ rõ ràng. – Arnab

0

Bạn cần phải viết để

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

trong file js đầu tiên bạn

+12

Ugh, xin đừng ** không ** biện hộ bằng cách sử dụng 'document.write()'. –

+7

@Matt Ball: bạn nói đúng, nhưng kể từ khi Vahan mới ở đây, bạn có thể muốn giải thích tại sao. – Konerak

+8

@Konerak: [đây là lý do] (http://stackoverflow.com/questions/802854/why-is-document-write-considered-a-bad-practice). –

10

Tôi không đồng ý với nhà phê bình về kỹ thuật document.write (xem suggestion of Vahan Margaryan). Tôi thích cách document.getElementsByTagName('head')[0].appendChild(...) (xem suggestion of Matt Ball), nhưng có một vấn đề quan trọng: thứ tự thực thi tập lệnh được bao gồm trong quá trình thực hiện. Tôi phải mô tả vấn đề chính xác hơn bên dưới.

Gần đây tôi dành nhiều thời gian để tái sản xuất one close problem. Cũng biết jQuery plugin sử dụng cùng một kỹ thuật (xem src here) để tải các tập tin, nhưng những người khác nhau đã báo cáo vấn đề với làm việc này. Tôi có thể mô tả vấn đề như sau. Hãy cho chúng tôi bạn có thư viện JavaScript bao gồm nhiều tập lệnh và một số loader.js tải tất cả các phần. Một số từ các bộ phận phụ thuộc từ người khác. Hãy cho chúng tôi bạn bao gồm một tập lệnh main.js khác trên <script> sử dụng các đối tượng từ loader.js ngay sau loader.js. Vấn đề là đôi khi, main.js được thực thi trước khi tất cả các tập lệnh được tải bởi loader.js. Việc sử dụng $(document).ready(function() {/*code here*/}); bên trong của tập lệnh main.js cũng có thể không hữu ích. Việc sử dụng tầng xếp chồng onload xử lý sự kiện trong loader.js sẽ theo sau tuần tự thay vì tải song song các tập lệnh và sẽ khó sử dụng tập lệnh main.js cần được bao gồm ở đâu đó sau loader.js.

Tôi có thể tạo lại sự cố trong môi trường của mình và có thể thấy rằng thứ tự thực thi tập lệnh trong Internet Explorer 8 có thể là thứ tự bao gồm JavaScripts. Đó là vấn đề rất khó nếu bạn cần bao gồm một số kịch bản mà một trong những phụ thuộc từ người khác. Sự cố và được mô tả trong Loading Javascript files in parallel. Khi workaround được đề nghị sử dụng document.writeln:

document.writeln("<script type='text/javascript' src='Script1.js'></script>"); 
document.writeln("<script type='text/javascript' src='Script2.js'></script>"); 

Nó được mô tả rằng trong trường hợp "các kịch bản được tải xuống song song nhưng thực hiện theo thứ tự họ đang ghi vào trang". Sau khi thay đổi từ kỹ thuật document.getElementsByTagName('head')[0].appendChild(...) sang document.writeln Tôi chưa bao giờ thấy bất kỳ vấn đề nào khác.

Vì vậy, tôi khuyên bạn nên sử dụng document.writeln.

CẬP NHẬT: Nếu ai đó có lợi ích ông có thể thử tải (và tải lại) the page trong Internet Explorer (trang sử dụng document.getElementsByTagName('head')[0].appendChild(...) kỹ thuật) và so sánh với the fixed version sử dụng document.writeln. (Mã của trang là tương đối bẩn và không phải từ tôi, nhưng nó có thể được sử dụng để tái tạo các vấn đề mà tôi mô tả).

Các vấn đề liên quan