在Chrome和IE中单击后退按钮时,防止重新加载Ajax数据

Gre*_*eso 6 javascript ajax jquery back-button infinite-scroll

我目前正在一个网站上,主页显示最近的10个博客条目.当我向下滚动时,当我几乎到达屏幕上最后一项的末尾时,会自动加载另外10个博客条目,依此类推(这是无限滚动功能).

如果用户单击任何博客条目,则他/她将被带到另一个页面以显示有关该博客条目的详细信息.当用户单击后退按钮时,他/她将被带到显示条目的主页.

请注意,主页使用Ajax加载数据.

假设以下场景:

  1. 用户进入站点,并加载条目1到10(通过Ajax).

  2. 用户向下滚动,然后加载下一个10个,特别是条目11到20(也通过Ajax).请注意,页面现在显示为1到20.

  3. 用户向下滚动,现在加载条目21到30,在页面上显示总共1到30个博客条目.

  4. 用户点击条目25,显示条目25的页面.

  5. 用户单击后退按钮,将显示所有项目1到30.

现在,如果用户使用火狐,Opera或Safari浏览器,当用户执行步骤5(即,单击后退按钮返回到主页),那么博客条目只是显示在屏幕上,并没有被重新加载.但是,使用IE和Chrome时,当用户单击后退按钮时,将重新加载页面,并且仅显示项目1到10.

我不喜欢IE和Chrome的行为.用户应该看到第1项到第30项.我如何确保所有浏览器都像FireFox一样?

谢谢.

更新

这是我正在使用的代码

首先,她是我的HTML

<html>
    <body>

        <section id="content">
            <section id="articles">
                <!-- This section is filled by jQuery/Ajax -->
            </section>

            <section id="loading-spinner">
                <img src="ajax-loader.gif" />
            </section>

        </section>

    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

这是我的jQuery

/**
 * 
 * This file uses a bunch of programming concepts, but the most important one is ensuring ajax calls run as a critical section
 * ... (this means if ajax is already called, then another instance of JavaScript cannot get into the critical section)
 * 
 * .. For more details, please read: http://stackoverflow.com/questions/22150960/critical-section-in-javascript-or-jquery
 * 
 */


load_more_posts = function () {

    // If we almost reach the bottom of the document, then load more posts
    if ( jQuery(window).scrollTop() >= jQuery(document).height() - jQuery(window).height() - 300) {

        // If the value of the promise is not pending, then we can call the load_posts function (the load_posts function will change the status to pending when it is executing the ajax request)
        if (ajax_status.state() !== "pending") {
            load_posts();

        }
    }
};


function load_posts() {

    ajax_status = jQuery.ajax({

        type:       'post',

        dataType:   'json',

        beforeSend: function(xhr) {

            if(jQuery.data(document.body, 'load_page') == false) {
                xhr.abort();
            }

            else {
                // Show the spinner
                jQuery('#loading-spinner').visible();
            }



        },

        url:        '../link/to/get_poasts.php',

        data:       {
            action:             'load_posts',

            js_query_data:      query_data,
            js_page:        jQuery.data(document.body, 'page_to_load')

        },

        success:    function (response) {

            if (response.isSuccessful) {

                var number_of_post_items = response.posts_array.length;

                for (var i = 0; i < number_of_post_items; i++) {

                    // If the item is already returned from the database and posted. then we skip it, otherwise, keep insert a new record 
                    if (jQuery('#articles').find('#article-' + response.posts_array[i].post_id).length == 0) {

                        // Add 'article'
                        jQuery('#articles').append('<article id="article-' + response.posts_array[i].post_id + '"></article>');

                        // More code here to add details about each article, such as title, excerpt...etc.


                    }
                }




                // Increase the value of the page to load by 1, and save it.
                page = jQuery.data(document.body, "page_to_load");
                page = page + 1;
                jQuery.data(document.body, "page_to_load", page);



                jQuery(window).on('scroll', load_more_posts);

            }

            else {
                // Display error message
                jQuery('#articles').append('<div>' + response.message + '</div>');

                // Make sure no further AJAX requests are made
                jQuery.data(document.body, 'load_page', false);
            }

        }
    }).always(function() {

        // Hide the spinner
        jQuery('#loading-spinner').invisible();
    });

    return ajax_status;
}



// Create a new promise. This will be used to ensure that no two calls hit the critical section at the same time
// ... (the critical section in this case is the time when we retrieve data from the database. We only want one call at a time)

var ajax_status = new jQuery.Deferred();


jQuery(document).ready(function() {

    // Hide the loading spinner first
    jQuery('#loading-spinner').invisible();


    // We resolve the promise, making sure it is ready (this is an intial state)
    ajax_status.resolve();

    // Initial values that are used
    jQuery.data(document.body, 'page_to_load', 1);

    // This parameter is used to stop loading pages when no more items are available to be displayed 
    jQuery.data(document.body, 'load_page', true);



    // Initial loading of poasts
    load_posts();



    // Enable on scrolling to load more pasts (to allow infinite scrolling)
    jQuery(window).on('scroll', load_more_posts);


});
Run Code Online (Sandbox Code Playgroud)

Gre*_*eso 0

众所周知,这是我想出的解决方案,它在所有浏览器中都是一致的。不幸的是,该解决方案需要重新加载/刷新按钮来重新加载数据。我试图避免这种情况,但未能成功。在 IE 和 Chrome 都解决 bfcache 问题之前,我将坚持使用此解决方案。

首先,这是新的 html

<html>
    <body>

        <section id="content">

            <a id="refresh">
                <img src="link/to/refresh.png" title="Refresh" alt="refresh" />
            </a>

            <section id="articles">
                <!-- This section is filled by jQuery/Ajax -->
            </section>

            <section id="loading-spinner">
                <img src="ajax-loader.gif" />
            </section>

        </section>

    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

这是 JavaScript

/**
 * 
 * This file uses a bunch of programming concepts, but the most important one is ensuring ajax calls run as a critical section
 * ... (this means if ajax is already called, then another instance of JavaScript cannot get into the critical section)
 * 
 * .. For more details, please read: http://stackoverflow.com/questions/22150960/critical-section-in-javascript-or-jquery
 * 
 */


load_more_posts = function () {

    // If we almost reach the bottom of the document, then load more posts
    if ( jQuery(window).scrollTop() >= jQuery(document).height() - jQuery(window).height() - 300) {

        // If the value of the promise is not pending, then we can call the load_posts function (the load_posts function will change the status to pending when it is executing the ajax request)
        if (ajax_status.state() !== "pending") {
            load_posts();

        }
    }
};


function load_posts() {

    ajax_status = jQuery.ajax({

        type:       'post',

        dataType:   'json',

        beforeSend: function(xhr) {

            if(jQuery.data(document.body, 'load_page') == false) {
                xhr.abort();
            }

            else {
                // Show the spinner
                jQuery('#loading-spinner').visible();
            }



        },

        url:        '../link/to/get_poasts.php',

        data:       {
            action:             'load_posts',

            js_query_data:      query_data,
            js_page:            sessionStorage.getItem("page_to_load")

        },

        success:    function (response) {

            if (response.isSuccessful) {

                var number_of_post_items = response.posts_array.length;

                for (var i = 0; i < number_of_post_items; i++) {

                    // If the item is already returned from the database and posted. then we skip it, otherwise, keep insert a new record 
                    if (jQuery('#articles').find('#article-' + response.posts_array[i].post_id).length == 0) {

                        // Add 'article'
                        jQuery('#articles').append('<article id="article-' + response.posts_array[i].post_id + '"></article>');

                        // More code here to add details about each article, such as title, excerpt...etc.

                        var history_session = get_history_session_name();
                        var history = sessionStorage.getItem(history_session);
                        var article_content = jQuery('#articles').find('#aarticle-' + response.posts_array[i].post_id)[0].outerHTML;

                        sessionStorage.setItem(history_session, history + article_content);

                    }
                }




                // Increase the value of the page to load by 1, and save it.
                page = parseInt(sessionStorage.getItem("page_to_load"));
                page = page + 1;
                sessionStorage.setItem("page_to_load", page);


                jQuery(window).on('scroll', load_more_posts);

            }

            else {
                // Display error message
                jQuery('#articles').append('<div>' + response.message + '</div>');

                // Make sure no further AJAX requests are made
                jQuery.data(document.body, 'load_page', false);
            }

        }
    }).always(function() {

        // Hide the spinner
        jQuery('#loading-spinner').invisible();
    });

    return ajax_status;
}




function get_history_session_name () {
    session_name = 'history___' + escape(location.href);
    return session_name;
}




// Create a new promise. This will be used to ensure that no two calls hit the critical section at the same time
// ... (the critical section in this case is the time when we retrieve data from the database. We only want one call at a time)

var ajax_status = new jQuery.Deferred();


jQuery(document).ready(function() {

    // Hide the loading spinner first
    jQuery('#loading-spinner').invisible();


    // We resolve the promise, making sure it is ready (this is an intial state)
    ajax_status.resolve();

    // This parameter is used to stop loading pages when no more items are available to be displayed 
    jQuery.data(document.body, 'load_page', true);


    // Get the name of the history session
    var history_session = get_history_session_name();

    if (sessionStorage.getItem(history_session) === null) {

        // Set the history session storage
        sessionStorage.setItem(history_session, "");


        // Initial values that are used
        sessionStorage.setItem("page_to_load", 1);

        // Load the posts
        load_posts();

    }


    // Load from history when the back button is clicked
    else {
        jQuery('#articles').append(sessionStorage.getItem(history_session));
    }



    // Enable on scrolling to load more pasts (to allow infinite scrolling)
    jQuery(window).on('scroll', load_more_posts);


    // Reload data when the refresh button is clicked
    // ... We are using a refresh button because if we go to a page that already had history, ...
    // ... and even though we went to that page without using the back button (i.e, via links or directly via the url), ...
    // ... then the history session will be displayed. ...
    // ... Therefore a reload button is needed to overcome this problem if you like to reload data
    jQuery("#refresh").click(function () {

        // Reset/clear the articles section first
        jQuery('#articles').html("");

        // reset the 'load_page' variable
        jQuery.data(document.body, 'load_page', true);


        // Reset/clear the history session storage
        sessionStorage.setItem(history_session, "");

        // Start with loading page 1
        sessionStorage.setItem("page_to_load", 1);

        // Load the posts
        load_posts();
    });

});
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。