首先對加載頁面的地址進行判斷,如果不符合要求,進行相對應的修改處理,然后使用history.pushState方法向瀏覽器記錄(history對象)中添加一個新記錄。然后通過ajax將需要的頁面地址賦值給url屬性,然后會返回一個來自延遲的對象的jqXHR對象,我們可以附加一個成功回調使用.done()
方法。在.done方法中實現將返回的text/html格式數據經過過濾css和js賦值給需要呈現頁面(例如div)的容器中。
//result 返回的頁面數據 contextArea 呈現頁面的容器 result = String(result) .replace(/<(title|link|meta|script)([\s\>])/gi, '<div class="hidden ajax-append-$1"$2') .replace(/<\/(title|link|meta|script)\>/gi, '</div>') contentArea.empty().html(result);
我沒有將返回的頁面數據直接賦值到容器中,如果頁面的數據內容包含script和css標簽的話,直接將頁面數據賦值到容器中后,會發送請求將這些文件加載到主頁面上,如果遇到已加載的文件或者一些不必要加載的文件而不能進行過濾處理,所以先將一些不是內容的標簽元素通過regex替換成帶有相關標簽名稱樣式的div,然后過濾移除加載等一系列操作。比如移除已存在的css引用文件標簽,重新加載未存在的css引用文件標簽:

setTimeout(function () { $('head').find('link.ajax-stylesheet').remove(); contentArea.find('.ajax-append-link').each(function (e) { var $link = $(this), t_link = $link.attr('href'); if (t_link) { if ($('head [href="' + t_link + '"]').length == 0) { var new_link = $('<link />', { type: 'text/css', rel: 'stylesheet', 'class': 'ajax-stylesheet' }) new_link.appendTo('head'); new_link.attr('href', t_link); } } $link.remove(); }); }, 10);
同樣在操作js的時候也可以通過相同的原理操作處理。我們發現頁面的內容發生變化了,而瀏覽器的地址沒有發生變化,即無法實現瀏覽器的前進后退功能。我們需要利用ocation的hash部分和使用window.onhashchange來實現。hash是瀏覽器地址#后面的部分,當只有hash部分發生變化時,瀏覽器的歷史記錄會產生記錄,但不會向服務器發出請求,這時按后退鍵地址欄的uri會變化但頁面內容不變。通過window.onhashchange事件來監聽hash值的更改。

$(window).off('hashchange').on('hashchange', function () { var hash = $.trim(window.location.hash); if (!hash || hash == '') { contentArea.empty(); return; } hash = hash.replace(/^(\#\!)?\#/, ''); loadHtml(hash); }).trigger('hashchange', [true]);
頁面加載的時候不會觸發onhashchange事件,所以在代碼的最后追加了trigger() 方法。