2010-05-06 39 views
5

Với một ứng dụng trang duy nhất, nơi tôi thay đổi băm và tải và chỉ thay đổi nội dung của trang, tôi đang cố gắng quyết định cách quản lý JavaScript mà mỗi " trang "có thể cần.Thực tiễn tốt nhất quản lý JavaScript trên một ứng dụng một trang

Tôi đã có một mô-đun Lịch sử theo dõi băm vị trí có thể trông giống như domain.com/#/company/about và lớp Trang sẽ sử dụng XHR để lấy nội dung và chèn nó vào khu vực nội dung.

function onHashChange(hash) { 
    var skipCache = false; 
    if(hash in noCacheList) { 
     skipCache = true; 
    } 
    new Page(hash, skipCache).insert(); 
} 


// Page.js 
var _pageCache = {}; 
function Page(url, skipCache) { 

    if(!skipCache && (url in _pageCache)) { 
     return _pageCache[url]; 
    } 
    this.url = url; 
    this.load(); 

} 

Bộ nhớ cache sẽ cho phép các trang đã được tải bỏ qua XHR. Tôi cũng đang lưu trữ nội dung vào một tài liệuFragment, và sau đó kéo nội dung hiện tại ra khỏi tài liệu khi tôi chèn Page mới, vì vậy tôi trình duyệt sẽ chỉ phải xây dựng DOM cho đoạn một lần.

Bỏ qua bộ nhớ cache có thể được mong muốn nếu trang có dữ liệu nhạy cảm về thời gian.

Đây là những gì tôi cần trợ giúp quyết định: Rất có khả năng bất kỳ trang nào được tải sẽ có một số JavaScript của riêng chúng để kiểm soát trang. Giống như nếu trang sẽ sử dụng Tabs, cần một trình chiếu, có một số loại hoạt hình, có dạng ajax hoặc những gì bạn có.

Cách chính xác nhất để tải JavaScript đó vào trang là gì? Bao gồm các thẻ script trong documentFragment Tôi lấy lại từ XHR? Điều gì sẽ xảy ra nếu tôi cần bỏ qua bộ đệm và tải xuống lại đoạn. Tôi cảm thấy chính xác cùng một JavaScript được gọi là lần thứ hai có thể gây xung đột, như redeclaring các biến tương tự.

Có cách nào tốt hơn để đính kèm tập lệnh vào đầu khi chụp Page mới? Điều đó sẽ yêu cầu trang gốc biết tất cả các tài sản mà mọi trang khác có thể cần. Ngoài việc biết cách tốt nhất để bao gồm mọi thứ, tôi có cần phải lo lắng về việc quản lý bộ nhớ hay không, và có thể rò rỉ tải rất nhiều các bit JavaScript khác nhau vào một cá thể trang đơn không? Không.

+0

Ứng dụng một trang là gì? –

+1

Nơi bạn tải trong trang đầu tiên từ máy chủ và mọi thứ khác sử dụng XHR, thay vì yêu cầu toàn bộ trang. Facebook là một ví dụ. – seanmonstar

+0

jQuery là bạn của bạn. Mua cho nó một thức uống. –

Trả lời

0

Tôi chưa bao giờ xây dựng trang web như vậy nên tôi không biết đó có phải là thực hành nbest hay không, nhưng tôi sẽ đặt một số thông tin kiểm soát (như nhận xét hoặc tiêu đề HTTP) trong phản hồi và cho phép tập lệnh trình tải xử lý dư thừa/phụ thuộc cheching và thêm các thẻ script vào tiêu đề.

0

Bạn có quyền kiểm soát các trang đó đang được tải không? Nếu không, tôi khuyên bạn nên chèn trang được tải vào trong một Khung nội tuyến.

Lấy các tập lệnh trang ra khỏi ngữ cảnh của chúng và chèn chúng vào đầu hoặc thêm chúng vào phần tử HTML khác có thể gây ra sự cố trừ khi bạn biết chính xác cách trang đang xây dựng.

Nếu bạn có toàn quyền kiểm soát các trang đang được tải, tôi khuyên bạn nên chuyển đổi tất cả HTML thành JS. Nghe có vẻ kỳ lạ nhưng thực ra, một công cụ chuyển đổi HTML-> JS không xa lắm. Bạn có thể bắt đầu với Pure JavaScript HTML Parser và sau đó để cho trình phân tích cú pháp tạo ra mã JS, điều đó xây dựng DOM bằng cách sử dụng JQuery chẳng hạn. Tôi đã thực sự đi xuống con đường đó một thời gian trước đây trên một webapp mà tôi bắt đầu làm việc trên, nhưng bây giờ tôi đưa nó cho một nhà thầu chuyển đổi tất cả các trang JS thuần túy của tôi thành HTML + JQuery, bất cứ điều gì làm cho anh ta công việc hàng ngày sản xuất, tôi không quan tâm, nhưng tôi đã thực sự vào cách tiếp cận JS webapp thuần túy và chắc chắn sẽ thử nó.

+0

Tôi có quyền kiểm soát các trang. Tôi đã xem xét một phân tích cú pháp JS. Nhưng tôi đã tạo các trang trong PHP, và vì PHP nhanh hơn nhiều so với JS, tôi chỉ trả về HTML. – seanmonstar

1

Nếu tôi hiểu đúng trường hợp, bạn đang cố gắng thực hiện một trang web hiện có các trang đã được tạo cho điều hướng thông thường và bạn muốn kéo chúng xuống qua ajax để tự lưu lại trang?

Sau đó, khi điều này xảy ra, bạn không cần phải tải lại thẻ tập lệnh cho các trang đó, trừ khi chúng không được tải lên trang?

Nếu đó là trường hợp, bạn có thể thử để lấy tất cả các thẻ từ trang trước khi chèn html mới vào dom:

//first set up a cache of urls you already have loaded. 
var loadedScripts = []; 

//after user has triggered the ajax call, and you've received the text-response 
function clearLoadedScripts(response){ 
    var womb = document.createElement('div'); 
    womb.innerHTML = response; 
    var scripts = womb.getElementsByTagName('script'); 
    var script, i = scripts.length; 
    while (i--) { 
     script = scripts[i]; 
     if (loadedScripts.indexOf(script.src) !== -1) { 
      script.parentNode.removeChild(script); 
     } 
     else { 
      loadedScripts.push(script.src); 
     } 
    } 

    //then do whatever you want with the contents.. something like: 
    document.body.innerHTML = womb.getElementsByTagName('body')[0].innerHTML); 

} 
+0

Đây là một triển khai khá tuyệt vời ... – gnarf

0

Đối với tôi nó có vẻ như bạn đang tạo ra một ứng dụng duy nhất trang ngay từ đầu (nghĩa là không tính lại một trang web hiện có).

Một số tùy chọn tôi có thể nghĩ:

  1. Hãy để kiểm soát máy chủ mà thẻ script có. chuyển danh sách các thẻ tập lệnh đã tải với yêu cầu XHR và yêu cầu máy chủ phân loại các tập lệnh bổ sung nào cần được tải.
  2. Tải tất cả tập lệnh trước (có thể thêm chúng vào DOM sau trang đã tải để tiết kiệm thời gian) và sau đó quên nó. Đối với các tập lệnh cần khởi chạy giao diện người dùng, chỉ cần có mỗi lệnh gọi trang được yêu cầu bao gồm thẻ tập lệnh gọi hàm init toàn cầu với tên trang.
  3. Yêu cầu mỗi trang được yêu cầu gọi hàm JS liên quan đến các tập lệnh tải/lưu vào bộ nhớ cache. Chức năng này có thể truy cập được từ phạm vi toàn cầu và sẽ trông giống như sau: require_scripts('page_1_init', 'form_code', 'login_code') Sau đó, chỉ cần giữ chức năng giữ một danh sách các tập lệnh đã tải và chỉ chắp thêm các thẻ DOM script cho các tập lệnh chưa được tải.
0

Bạn có thể sử dụng một bộ nạp kịch bản như YUI Loader, LAB.js hoặc khác như jaf

Jaf cung cấp cho bạn với cơ chế để tải xem (HTML trích dẫn) và js tương ứng của họ, các file css để tạo trang duy nhất ứng dụng. Kiểm tra ứng dụng danh sách cần làm mẫu. Mặc dù nó không hoàn chỉnh, vẫn còn rất nhiều thư viện hữu ích mà bạn có thể sử dụng.

1

Oh boy là bạn may mắn. Tôi đã thực hiện tất cả nghiên cứu này cho dự án của riêng tôi.

1: Sự kiện băm/quản lý bạn nên sử dụng là Ben Alman của BBQ: http://benalman.com/projects/jquery-bbq-plugin/

2: Để làm cho công cụ tìm kiếm yêu bạn, bạn cần phải làm theo bộ rất rõ ràng này của quy tắc: http://code.google.com/web/ajaxcrawling/docs/specification.html

Tôi thấy điều này muộn và trò chơi và đã phải loại bỏ rất nhiều mã của tôi. Nghe có vẻ như bạn sẽ phải loại bỏ một số quá, nhưng bạn sẽ nhận được nhiều hơn từ nó như là một hệ quả.

Chúc may mắn!

+0

cảm ơn bài viết ajaxcrawling google.com đó. Tôi đang tìm kiếm điều đó. – seanmonstar

+0

NP! Vui lòng đánh dấu đây là câu trả lời nếu đó là những gì bạn đang tìm kiếm. – Matrym

+0

tôi đã tìm kiếm liên kết bản thân mình, nhưng tôi không nghĩ rằng điều này trả lời câu hỏi, xin lỗi. Tôi quan tâm nhiều hơn đến việc quản lý Javascript theo yêu cầu của các trang khác nhau, xử lý các biến mới được khai báo, các sự kiện đính kèm và tách và quản lý bộ nhớ. – seanmonstar

0

Cá nhân, tôi sẽ truyền JSON thay vì HTML liệu:

{ 
    "title": "About", 
    "requires": ["navigation", "maps"], 
    "content": "<div id=…" 
} 

này cho phép bạn gửi siêu dữ liệu, như một loạt các kịch bản yêu cầu, cùng với các nội dung.Sau đó, bạn sẽ sử dụng trình tải tập lệnh, như một trong những trình được đề cập ở trên, hoặc của chính bạn, để kiểm tra xem cái nào đã được tải và kéo xuống những cái không (chèn chúng vào <head>) trước khi hiển thị trang.

Thay vì bao gồm tập lệnh nội tuyến cho logic cụ thể theo từng trang, tôi muốn sử dụng các lớp, id và thuộc tính được xác định trước trên các phần tử cần xử lý đặc biệt. Bạn có thể kích hoạt sự kiện "đầu hàng" hoặc để mỗi phần logic đăng ký một cuộc gọi lại mà trình tải trang của bạn sẽ gọi sau khi trang được hiển thị hoặc được tải lần đầu tiên.

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