![](/img/trans.png)
[英]How to use the History API or history.js to change the “active” link appropriately when the page is refreshed or when the back button is pressed?
[英]How to avoid rendering the initial view of browsing session when page is refreshed from somewhere else in the application using History.js?
我正在非常努力地為IE 8和9實現history.js一個jQuery插件 。該演示在IE10 +和其他現代瀏覽器中似乎不錯,但我無法理解IE <= 9的問題。 該演示是一個asp.net mvc5應用程序,我想在此提供單頁用戶體驗,其中我只是加載部分視圖並通過ajax執行后期操作。 所有視圖都在我的主視圖中的#shell
div中加載。 可能是我缺少了一些東西!
我的演示應用程序以http://localhost:1089/
開頭,這是呈現登錄頁面的第一個請求。 任何其他pushState()都會導致URL發生更改,並附加#Home #Home/About?ref=one
。
以下是我在layout.cshtml中執行的腳本,該腳本僅加載一次:
(function (window, undefined) {
History.Adapter.bind(window, 'statechange', function () {
var state = History.getState();
if (state.data.options == undefined) {
alert("options is undefined");
var options = {
url: state.url,
type: "GET",
dataType: "html"
};
GetPartial(options);
} else {
GetPartial(state.data.options);
}
});
})(window);
$(document).on('click', 'a', function (e) {
e.preventDefault();
var options = {
url: $(this).prop('href'),
type: "GET",
dataType: "html"
};
History.pushState({ options: options }, $(this).text(), $(this).prop('href'));
});
function GetPartial(options) {
if (options) {
$.ajax({
url: options.url,
type: options.type || 'GET',
dataType: options.datatype || 'html',
async: true,
data: options.dataToPost,
beforeSend: function() {
$("#loaderMain").show();
},
complete: function() {
$("#loaderMain").hide();
},
cache: false,
}).success(function(response, status, xhr) {
var ct = xhr.getResponseHeader("content-type") || "";
if (ct.indexOf('html') > -1) {
// returned result is of type html, so act accordingly
if (options.selector == undefined) {
InjectContentToShell(response);
} else {
$(options.selector).empty().append(response);
}
} else if (ct.indexOf('json') > -1) {
// returned result is of type json, so act accordingly
}
}).fail(function(e) {
console.log(e);
});
}
}
function InjectContentToShell(content) {
$('#shell').fadeOut(100, function () {
$(this).empty().append(content);
}).fadeIn(100);
}
呈現此第一頁時,我通過pushState方法向“歷史記錄”中添加一個條目,如下所示:
$('#submit').on('click', function (e) {
e.preventDefault();
var formInstance = $(this).closest('form'),
dataToPost = formInstance.serialize();
var options = {
url: formInstance.prop('action'),
type: formInstance.prop('method'),
dataType: "html",
dataToPost: dataToPost
};
History.pushState({ options: options }, "Home - All Summary Views", "/Home/Index");
});
將狀態推到上面,在html4瀏覽器中將URL更改為http://localhost:1089/#Home/Index
即可。 我能夠前進和后退。 這很好。
現在,當我在html4瀏覽器中刷新頁面時,發送到服務器的請求是第一個URL,即http://localhost:1089/
,它將第一個視圖帶到客戶端。 因此,用戶可以看到第一頁,即登錄屏幕。 然后觸發statechange
事件,狀態url仍然記住刷新頁面的最后一個url,並向服務器發送對該URL的新請求。 然后將響應注入到外殼中。
因此,問題是-在刷新頁面時,用戶立即獲得兩個視圖-初始頁面,用戶在該頁面上開始了他的瀏覽會話,並且很快從服務器加載了第二個頁面,並通過動畫將其添加到了外殼,就像觸發statechange事件時一樣, History.getState()
仍會記住最后一個網址。
我不想在刷新頁面上顯示此初始頁面。 如果解決了這個問題,那么我認為此history.js一切正常!
在本文中,還提到了上述問題作為書簽的概念。 請參閱第一個圖及其上方的文字。
我的演示應用程序在html5瀏覽器中可以正常工作,因為在每個History.pushState()
,瀏覽器的URL都更改為我指定的URL。 刷新頁面后,請求將根據該URL發送到服務器,而不是啟動瀏覽會話中的第一個URL。
在嘗試了許多事情之后,我想出了以下解決方案,以避免顯示第一個視圖,即使用html4瀏覽器向用戶顯示登錄頁面:
我創建了一個視圖“索引”,它是正在渲染的第一個視圖。 其中沒有任何html內容,但是具有以下腳本:
<script>
$(function () {
if (History.getCurrentIndex() == 0) {
var options = {
url: "/Account/Login",
type: "GET",
dataType: "html"
};
History.pushState({ options: options }, "Login Page", "/Account/Login");
}
});
</script>
上面的代碼檢查當前索引是否為0。 如果為0,則表示用戶剛剛開始瀏覽歷史記錄,並且應該顯示登錄屏幕。 如果不為0,則表示用戶正在應用程序中進行用戶訪問的其他步驟,該步驟不執行任何操作。 並且一旦呈現此視圖,就會觸發statechange
事件,該事件已經具有有關用戶請求刷新的頁面的URL信息。 根據我問題中上述狀態更改事件處理程序的邏輯,該資源是從服務器請求的,並注入了#shell
容器中。
上面的解決方案效果很好,並且為用戶提供了與html5瀏覽器相同的體驗。 上面的代碼對我有用,但是很高興知道別人是否還有其他解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.