簡體   English   中英

在單頁應用上管理JavaScript的最佳實踐

[英]Best practices managing JavaScript on a single-page app

使用單頁面應用程序,我更改哈希值並加載並僅更改頁面內容,我正在嘗試決定如何管理每個“頁面”可能需要的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位加載到單個頁面實例中的可能泄漏嗎?

如果我正確理解了這個案例,那么您正試圖建立一個當前已經為正常導航制作頁面的網站,並且您想通過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);

}

哦,男孩,你好運。 我剛剛為自己的項目做了所有這些研究。

1:你應該使用的哈希事件/經理是Ben Alman的BBQ: http//benalman.com/projects/jquery-bbq-plugin/

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

我發現這個晚了,游戲不得不廢棄我的很多代碼。 聽起來你也不得不廢棄一些,但結果你會得到更多。

祝好運!

我從來沒有構建過這樣的網站,所以我不知道這是不是最好的做法,但我會在響應中放置某種控制信息(如注釋或HTTP標頭),讓加載器腳本處理冗余/依賴cheching並將腳本標簽添加到標頭中。

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

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

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

我實際上剛剛開始使用我開始研究的webapp,但是現在我把它交給了一個承包商,后者將我所有的純JS頁面轉換為HTML + JQuery,無論是什么使他的日常工作富有成效,我不在乎,但我真的很喜歡那種純粹的JS webapp方法,並且肯定會嘗試它。

對我來說,這聽起來就像你從一開始就創建一個單頁應用程序(即不重新分解現有網站)。

我能想到的幾個選項:

  1. 服務器控制包含哪些腳本標記 使用XHR請求傳遞已加載的腳本標記列表,並讓服務器整理出需要加載的其他腳本。
  2. 事先加載所有腳本 (可能在頁面加載后將它們添加到DOM以節省時間)然后忘記它。 對於需要初始化UI的腳本,只需讓每個請求的頁面調用都包含一個腳本標記,該標記使用頁面名稱調用全局init函數。
  3. 讓每個請求的頁面調用一個處理加載/緩存腳本JS函數 這個函數可以從全局范圍訪問,看起來像這樣: require_scripts('page_1_init', 'form_code', 'login_code')然后讓函數保留一個已加載腳本的列表,只為那些require_scripts('page_1_init', 'form_code', 'login_code')腳本附加DOM腳本標記尚未加載。

您可以使用像YUI Loader,LAB.js或其他類似jaf的腳本加載器

Jaf為您提供了加載視圖(HTML代碼段)及其各自的js,css文件以創建單頁應用程序的機制。 查看示例待辦事項列表應用程序。 雖然它不完整,但仍然可以使用許多有用的庫。

就個人而言,我會傳輸JSON而不是原始HTML:

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

這使您可以發送元數據,如所需腳本數組以及內容。 然后,您可以使用腳本加載器(如上面提到的那個)或您自己的腳本加載器來檢查已加載的腳本加載器,並在呈現頁面之前下拉那些不加載的腳本加載器(將它們插入<head> ) 。

我不使用腳本內聯特定於頁面的邏輯,而是在需要特殊處理的元素上使用預定的類,ID和屬性。 您可以觸發“onrender”事件,或者讓每個邏輯片段注冊一個渲染回調,在第一次呈現或加載頁面后,頁面加載器將調用該回調。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM