2010-05-06 57 views
5

使用單頁面應用程序,我在其中更改散列並加載並更改頁面內容,我試圖決定如何管理JavaScript,每個「頁面「可能需要。管理單頁面應用程序中的JavaScript的最佳實踐

我已經有一個監控位置哈希的模塊,它可能看起來像domain.com/#/company/about,而Page類將使用XHR獲取內容並將其插入到內容區域。

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(); 

} 

緩存應該讓已經加載的頁面跳過XHR。我還將內容存儲到documentFragment中,然後在插入新的Page時將當前內容拉出文檔,因此瀏覽器只需構建一次片段的DOM。

如果頁面中包含時間敏感數據,則可能需要跳過緩存。

以下是我需要幫助的決定:很有可能任何加載的頁面都會有一些自己的JavaScript來控制頁面。就像頁面將使用Tabs一樣,需要幻燈片放映,具有某種動畫形式,具有ajax形式或者擁有你自己的東西。

什麼是將JavaScript加載到頁面的最佳方式?將腳本標籤包含在我從XHR中獲取的documentFragment中?如果我需要跳過緩存並重新下載片段,該怎麼辦?我覺得第二次調用完全相同的JavaScript可能會導致衝突,例如重新聲明相同的變量。

當抓取新的Page時,更好的方法是將腳本附加到頭部嗎?這將要求原始頁面知道每個其他頁面可能需要的所有資產。

除了知道包含所有內容的最佳方式之外,我是否也不需要擔心內存管理,以及將很多不同的JavaScript位加載到單個頁面實例中的可能泄漏?

+0

什麼是單頁面應用程序? – 2010-05-06 16:49:44

+1

從服務器加載到第一頁的地方,其他所有內容都使用XHR而不是整頁請求。 Facebook就是一個例子。 – seanmonstar 2010-05-06 16:52:08

+0

jQuery是你的朋友。買一杯飲料。 – 2010-05-06 16:54:31

回答

0

我從來沒有建立過這樣的網站,所以我不知道這是否是最好的做法,但我會在響應中放入某種控制信息(如評論或HTTP標頭),並讓加載腳本處理冗餘/依賴cheching和添加腳本標籤到頭。

0

您是否可以控制正在加載的頁面?如果不是,我會建議將加載的頁面插入IFrame中。

將頁面腳本從其上下文中取出並將它們插入到頭部或將它們添加到另一個HTML元素可能會導致問題,除非您確切知道如何構建頁面。

如果您完全控制了正在加載的頁面,我建議您將所有HTML轉換爲JS。這聽起來很奇怪,但實際上,HTML-> JS轉換器並不遙遠。你可以從Pure JavaScript HTML Parser開始,然後讓解析器輸出JS代碼,例如使用JQuery構建DOM。

我實際上一段時間以前就開始在一個webapp上開始工作,但現在我把它交給了一個承包商,他將我所有的純JS頁面轉換爲HTML + JQuery,日常工作的生產力,我不在乎,但我真的進入了純粹的JS webapp方法,一定會嘗試。

+0

我確實可以控制頁面。我正在考慮一個JS解析器。但是我已經在使用PHP創建頁面了,由於PHP比JS快得多,我只是要返回HTML。 – seanmonstar 2010-05-07 18:29:17

1

如果我理解正確的話,你正試圖採取目前已經爲正常航行做頁面的網站,你想拉下來通過AJAX,保存自己的頁面重載?

然後,當發生這種情況,你需要不會重新加載腳本標記這些網頁,除非他們沒有加載到已經頁面會?

如果是這樣的話,你可以嘗試插入新的HTML到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

這是一個非常棒的實現... – gnarf 2010-06-09 06:59:58

0

對我來說,它聽起來就像你正在創建一個單頁的應用程序從一開始(即不重新考慮現有網站)。

我能想到的有幾個選項:

  1. 讓該腳本標籤包括在的服務器控件。用XHR請求傳遞一個已經加載的腳本標籤的列表,並讓服務器確定需要加載哪些附加腳本。
  2. 加載所有腳本(可能將它們添加到DOM 之後頁面已加載以節省時間),然後忘掉它。對於需要初始化UI的腳本,只需要每個請求的頁面調用都包含一個腳本標記,該腳本標記使用頁面名稱調用全局init函數。
  3. 讓每個請求的頁面調用JS 功能與加載/緩存腳本交易。這個函數可以從全局範圍訪問,看起來像這樣:require_scripts('page_1_init', 'form_code', 'login_code')然後只需要該函數保存已加載腳本的列表,並只爲尚未加載的腳本附加DOM腳本標記。
0

你可以使用腳本管理器,例如YUI加載,LAB.js或其他類似jaf

JAF提供了機制加載的意見(HTML片段)和它們各自的JS,CSS文件,以創建單個頁面應用。查看示例待辦事項列表應用程序。雖然它不完整,但仍然可以使用許多有用的庫。

1

哦,男孩,你是運氣。我只是爲我自己的項目做了所有這些研究。

1:你應該用散列事件/經理是本Alman的BBQ: http://benalman.com/projects/jquery-bbq-plugin/

2:爲了使搜索引擎愛你,你需要遵循這個非常明確的規則: http://code.google.com/web/ajaxcrawling/docs/specification.html

我發現這很晚和遊戲,不得不廢棄我的很多代碼。這聽起來像你將不得不放棄一些,但作爲結果,你會得到更多的東西。

祝你好運!

+0

感謝那google.com ajaxcrawling文章。我正在尋找那個。 – seanmonstar 2010-06-07 06:45:15

+0

NP!如果這是你要找的東西,請將其標記爲答案。 – Matrym 2010-06-07 09:03:06

+0

我正在尋找自己的鏈接,但我不認爲這回答了這個問題,對不起。我更感興趣的是各種頁面所需的JavaScript管理,處理新聲明的變量,附加和分離事件以及內存管理。 – seanmonstar 2010-06-08 21:43:27

0

就個人而言,我會發送JSON,而不是原始的HTML:

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

這使您可以發送元數據,如所需的腳本的陣列,與內容一起。然後,您可以使用腳本加載程序(如上面提到的腳本加載程序或您自己的腳本加載程序)來檢查哪些腳本加載器已經加載,並在呈現頁面之前將它們(將它們插入到<head>中)下拉。

而不是包含腳本內聯的頁面特定的邏輯,我會使用預先確定的類,ID和屬性的元素需要特殊處理。你可以觸發一個「onrender」事件,或者讓每一段邏輯都註冊一個on-render回調函數,在第一次渲染或加載頁面之後,頁面加載器將調用它。

相關問題