簡體   English   中英

當使用History.js從應用程序中的其他地方刷新頁面時,如何避免呈現瀏覽會話的初始視圖?

[英]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.

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