2010-09-19 60 views
4

據我所知,標題有點含糊,無所不包,所以請讓我試着縮小範圍。如何構建Facebook風格的Ajax網站

我想要的是關於如何開發一個主要是Ajax網站的建議,其中部分UI是異步加載的。這裏有一個問題:我想讓瀏覽器的後退/前進按鈕直觀地工作 - 這是Facebook取得了非常好的成就。

有誰知道Facebook使用的庫和設計模式?考慮到他們做得非常出色,將它們用作模型是非常有意義的,而不是試圖重新發明輪子。

我注意到,有很多在URL哈希回事:
http://www.facebook.com/home.php?#!/home.php?sk=bd

我敢肯定,必須有他們這樣做的一個很好的理由,我也不會感到驚訝如果這是我可以利用的東西。有人可以指出他們在這裏完成了什麼,以及那個?#!/home.php?sk=bd的每個部分用於什麼?當我看到home.php?sk=bd,當加載的原始頁面是home.php--這可能是他們允許鏈接到特定「頁面」的方式,儘管整個事件由home.php服務嗎?我特別驚訝。

解決每個問題並不是那麼重要 - 我只是在試圖表達我無法理解的東西 - 如果您願意的話,我會說「更大的圖片」。如果有人能給我一個更全面的答案,那就太棒了(特別是如果你能告訴我如何使用ASP.NET MVC來完成)。

在此先感謝!

+0

不是一個答案,但我相信重複哈希路徑是一個解決方案,用戶沒有腳本看到一些相關的頁面,如果不是正確的單擊鏈接/書籤後。 – 2010-09-19 23:13:06

+1

哦,順便說一句,#!是谷歌使用的一個避難所。由於您將製作一個AJAX網站,因此注意這一點非常重要。更多信息在這裏:http://searchengineland.com/googles-proposal-for-crawling-ajax-may-be-live-34411注意,當然它*已經工作*。 – 2010-09-19 23:15:46

+0

「#!」的用途這樣就可以在沒有瀏覽器強制頁面重新加載的情況下使用Javascript修改URL。這樣,您可以修改瀏覽器URL以匹配您的AJAX調用,而無需重新加載頁面。 – Jemes 2010-09-20 01:03:20

回答

2

我們已經建立了一個應用程序像你描述,這裏就是我們所做的最後:

  1. 服務器用專門的瀏覽器通過JSON數據討論。
    XML消息傳遞也可以,但在所有瀏覽器中都難以處理。
     
  2. 前端僅由靜態文件構建:HTML,CSS,JS。服務器只處理安全性和數據庫事務。
    所有HTML呈現客戶端與一個JavaScript模板引擎pure.js,它乾淨地分離HTML視圖和JS邏輯。
     
  3. 對於導航,我們使用散列鍵(#)作爲應用程序的狀態。例如:用戶正在看什麼人。在測試了許多解決方案之後,我們最終構建了一個非常簡單的解決方案,使用120ms的輪詢setInterval來檢查散列鍵的值是否有變化。

該應用程序非常靈敏,導航非常直觀。

編輯:
由於我們丟棄我們不再輪詢哈希值發生變化,而是用我使用的技術的類似麥克風的window.onhashchange

1

的IE6和IE7的支持。我的工具包的基本部分:

  • 一個javascript構建系統。我用螞蟻把我所有的小js源文件放到一個大的最終文件中。這樣我就可以保持我的文件儘可能小,而不用擔心必須將100個單獨的腳本導入到瀏覽器中。

  • 模板引擎。我使用的是Trimpath,並且一直很滿意。除了Trimpath之外,我還開發了自己的系統來處理包含和模板繼承,我用這些系統來處理我的模板代碼,然後交給Trimpath。

  • 模板文件預處理器將多行字符串轉換爲有效的javascript。這樣,我可以編寫常規的多行html,將其交給我的腳本,該腳本將其轉換爲javascript,然後可以將我的模板滾動到主js文件中,而不必單獨提供它們。

  • 處理異步調用的技術。有很多情況下,爲了渲染一個屏幕,我需要確保dataA,dataB和dataC被加載。我沒有創建服務器端調用「fetchDataABandC」,而是使用客戶端函數,可以指定「執行A,B和C,並在所有完成時調用此回調函數」。我也可以指定「依次執行A然後B然後C」。我發現自己做了很多事情的另一件事是設置函數,以便它們可以輕鬆地轉入異步調用。所以,通常,任何時候我有一個獲取數據的函數,而不是讓該函數返回一個值,我傳遞一個回調函數。例如,如果我將一些數據存儲在cookie中,稍後我決定將該數據移動到服務器,如果我用來獲取和設置數據的函數是基於回調的,則很容易換掉與服務器調用執行。

  • 緩存機制。我所有的服務器調用都是通過一個單一的「服務」對象訪問。我有一個包裹服務對象緩存對象,複製的每個單獨的方法對象,並添加一個名爲{methodName} Cached的附加方法,因此如果原始服務對象有一個名爲「getSubscriberDetails」的方法,緩存對象將爲其自身動態創建一個「getSubscriberDetails」方法,該方法鏈接回原始方法,一個「getSubscriberDetailsCached」方法,它將返回緩存的數據(如果存在的話),但會另有ca將原始函數(並緩存它返回的數據)。在內部,緩存使用由方法名和方法參數生成的鍵來存儲數據,因此如果我調用cache.getSubscriberDetailsCached(「subscriber1」),它不同於cache.getSubscriberDetailsCached(「subscriber2」)。

  • 在小部件之間進行通信的事件系統。我正在構建的軟件是聯繫人管理系統。如果我有一個列出所有用戶聯繫人的小部件,以及允許用戶添加和刪除聯繫人的另一個小部件,則需要通知聯繫人列表小部件發生了哪些變化。我沒有使用「添加聯繫人」小部件來保持每一個依賴於聯繫人列表的其他功能的意識,而是使用jquery的事件系統發送一個「contactsChanged」事件給任何具有「contactsChangedListener」類的dom對象。 。所以,我的「聯繫人列表」小部件在其最外層div中有「contactssChangedListener」類,並且我通過jQuery.bind將一個監聽器附加到「聯繫人列表」控制器中。當發送「contactsChanged」事件時,我的「聯繫人列表」小部件知道它需要刷新其聯繫人列表。

  • 基於哈希的導航。我使用jquery hashchange插件來幫助我監聽哈希變化。每個屏幕都與一個單獨的網址相關聯,您從一個屏幕移動到另一個屏幕的方式是更改網址。儘管我不使用直接鏈接。每個導航操作都會通過一個導航器對象,該對象可以配置爲執行某些操作,例如彈出警告消息,告訴用戶他們即將丟失未保存的更改。

+0

有意思......它看起來我們是在相同的小部件種類的任務;)雖然,我沒有選擇DOM,但JS對象註冊事件。我在測試時並不相信trimpath,併爲此構建了pure.js。 – Mic 2010-09-20 14:58:37

+0

小工具任務!我喜歡使用dom進行事件的註冊和註銷監聽器是非常自動的。如果您刪除了一個小部件,您不必擔心清理對該小部件的引用,它只會自動發生。 Pure.js是你的嗎?涼! – morgancodes 2010-09-20 15:20:11