Gre*_*eso 6 javascript ajax jquery back-button infinite-scroll
我目前正在一个网站上,主页显示最近的10个博客条目.当我向下滚动时,当我几乎到达屏幕上最后一项的末尾时,会自动加载另外10个博客条目,依此类推(这是无限滚动功能).
如果用户单击任何博客条目,则他/她将被带到另一个页面以显示有关该博客条目的详细信息.当用户单击后退按钮时,他/她将被带到显示条目的主页.
请注意,主页使用Ajax加载数据.
假设以下场景:
用户进入站点,并加载条目1到10(通过Ajax).
用户向下滚动,然后加载下一个10个,特别是条目11到20(也通过Ajax).请注意,页面现在显示为1到20.
用户向下滚动,现在加载条目21到30,在页面上显示总共1到30个博客条目.
用户点击条目25,显示条目25的页面.
用户单击后退按钮,将显示所有项目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)
众所周知,这是我想出的解决方案,它在所有浏览器中都是一致的。不幸的是,该解决方案需要重新加载/刷新按钮来重新加载数据。我试图避免这种情况,但未能成功。在 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)
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
3596 次 |
| 最近记录: |