2009-10-07 28 views
16

Mặc dù tôi gần như chắc chắn câu trả lời cho câu hỏi này sẽ là trình duyệt cụ thể, có bất kỳ trình duyệt nào xác định hành vi khi nhiều thẻ <script> được sử dụng và có cùng thuộc tính src không?Điều gì xảy ra nếu bạn sử dụng thẻ <script> với cùng thuộc tính "src" nhiều lần trong một tài liệu HTML?

Ví dụ ...

<script src="../js/foo.js"></script> 
... 

<!-- what happens here? --> 
<script src="../js/foo.js"></script> 

Lý do tôi hỏi câu hỏi này ở nơi đầu tiên, đó là trong trường hợp đặc biệt của tôi, tôi đang sử dụng quang cảnh một phần trong một ứng dụng ASP.NET MVC mà tận dụng JQuery . Tất cả các tệp JQuery JS đều được bao gồm trong tệp mẫu chính thông qua các thẻ tập lệnh. Tôi muốn thêm các thẻ script vào các tệp xem một phần để trong trường hợp chúng được sử dụng bên ngoài ngữ cảnh của khuôn mẫu chủ, chúng sẽ tự động bao gồm tất cả các tệp JS cần thiết và không dựa vào một khung nhìn hoặc khuôn mẫu khác để bao gồm chúng. Tuy nhiên, tôi chắc chắn không muốn làm cho các tệp JS phải được chuyển đến máy khách nhiều lần, hoặc bất kỳ tác dụng phụ nào khác có thể tác động tiêu cực đến trải nghiệm người dùng.

Suy nghĩ của tôi bây giờ là, nếu không phải tất cả, các trình duyệt chính (FF, Safari, IE, Opera) sẽ lưu một tệp JS vào lần đầu tiên được sử dụng, sau đó trên các thẻ script tiếp theo, trình duyệt sẽ sử dụng bản sao được lưu trong bộ nhớ cache nếu có và nếu nó chưa hết hạn. Tuy nhiên, hành vi bộ nhớ đệm thường có thể được thay đổi thông qua cấu hình trình duyệt, vì vậy nó không có vẻ quá "an toàn" để dựa vào bất kỳ loại hành vi bộ nhớ đệm nào.

Tôi có phải chấp nhận thực tế rằng các lượt xem một phần của tôi sẽ phụ thuộc vào các mẫu hoặc chế độ xem khác bao gồm các tệp JS thích hợp không?

Trả lời

10

Ngay cả khi chúng được lưu trong bộ nhớ cache, bạn có thể gặp sự cố vì cùng một mã sẽ được thực hiện hai lần. Ít nhất, điều này sẽ khiến trình duyệt mất nhiều thời gian hơn mức cần thiết. Và nó có thể gây ra lỗi, vì hầu hết mã JavaScript không được viết để được thực hiện hai lần. Ví dụ, nó có thể đính kèm cùng một trình xử lý sự kiện hai lần.

+0

+1 một số thư viện được bảo vệ chống lại sự bao gồm hai lần, nhưng theo như tôi thấy jQuery thì không.Đừng bao gồm nó hai lần. Bạn có thể nhận được các hành vi bất thường khi thư viện được instanced hai lần. – bobince

+0

Mã được thực hiện khi nó được gọi. Bạn có nghĩa là để nói nó sẽ được giải thích hai lần, đó là khá khác nhau, và điều đó tạo ra các vấn đề khác với bạn minh họa. –

+0

@austin mã sẽ được diễn giải và thực hiện khi nó được tải, giống hệt với JS. Ví dụ, 'function foo() {}' là một dòng mã, khi được thực thi, tạo một biến toàn cục mới có tên là foo và gán giá trị của một thân hàm cho nó. JW đang nói đây là vấn đề vì nó sẽ được thực hiện hai lần. –

1

Không xuất thẻ tập lệnh trực tiếp trong partials của bạn. Tạo một cơ chế để đăng ký các tệp kịch bản để đưa vào sau này. Cơ chế đó có thể chịu trách nhiệm chỉ bao gồm các tệp một lần.

+2

Tôi thích ý tưởng này. Bạn có thể tạo một trình trợ giúp với một phương thức có thể được gọi là IncludeScript ("../ js/foo.js") và có phương pháp đó theo dõi các tập lệnh nào đã được đưa vào yêu cầu hiện tại. "Bí quyết" duy nhất là lưu trữ dữ liệu trong phạm vi yêu cầu để chia sẻ thông tin về các tập lệnh nào đã được đưa vào giữa chế độ xem, mẫu và partials. Tôi không thực sự chắc chắn làm thế nào để đi về việc này trong ASP.NET MVC, nhưng tôi chắc chắn đó là doable và hy vọng khá đơn giản –

+0

Để theo dõi trên các bình luận trước đó, ASP.NET MVC cung cấp một vài tùy chọn để lưu trữ request- dữ liệu phạm vi. Một tùy chọn là đối tượng từ điển ViewData, có sẵn trực tiếp dưới dạng thuộc tính cho chế độ xem, partials, templates hoặc HtmlHelper. Một tùy chọn khác là thuộc tính Items của HttpRequest/HttpRequestBase. Trong cả hai trường hợp, dữ liệu được lưu trữ trong các bộ sưu tập đó sẽ được duy trì trong suốt thời gian yêu cầu và có sẵn cho tất cả các chế độ xem, partials, templates và HtmlHelper được sử dụng trong yêu cầu. –

+0

Bạn không cần phải cuộn của riêng bạn, bạn có thể làm điều đó với (ví dụ) 'Page.ClientScript.RegisterClientScriptInclude (" jQuery ", );' – Tacroy

0

FF 3.5x, Chrome 4x chỉ bao gồm một lần.

:) IE 8 có hai bản sao (xem trong Developer Tools> tab Scripts có hai mục jquery-1.3.2.min.js)

0

gì xảy ra là JavaScript được đưa vào các thông dịch viên thời điểm nó được tải xuống. Trong trường hợp một va chạm không gian tên chỉ có tên biến, của một phạm vi nhất định, tồn tại để thực hiện. Thông thường, quy trình cuối cùng này chỉ ngăn chặn các vấn đề phát sinh bằng cách ghi đè các hàm vào trong trình thông dịch trước đó. Vấn đề là một hàm xác định phạm vi biến, mà các biến đó có thể là các hàm khác giới thiệu sau đó phạm vi không gian tên khác của các biến. Đó là một vấn đề bởi vì nếu các hàm chia sẻ cùng một giá trị tên và bao gồm các định nghĩa biến khác nhau thì có thể có sự rò rỉ trong đó các biến từ nguồn cấp dữ liệu vào trình thông dịch sớm tồn tại ngay cả sau khi hàm đó bị ghi đè.

Nếu cùng một tệp chính xác được bao gồm hai lần, sẽ không có vấn đề gì. Vấn đề xảy ra khi các phiên bản khác nhau của cùng một tệp được bao gồm hoặc các tệp khác nhau có cùng tên hàm được bao gồm. Bao gồm cả cùng một tệp hai lần có thể có nghĩa là nhiều lần truyền, đó là một sự lãng phí băng thông.

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