More informative sites are often paginated, and in the "next page", many websites use dynamic requests to avoid page refreshes. Although everyone is Ajax, from a few small details can be distinguished from the pros and cons. A small detail is the ability to support browser "back" and "forward" keys. This article discusses two approaches that allow the browser to move backwards and forwards, or to have Ajax be able to go back to the previous page or forward to the next page as if it were redirected to a new page.
Data implementation paging, the simplest way is to add multiple pages after the number of page, point "next page" when the page is redirected to page+1 new address. For example, Sina's news network is doing so, by changing the URL to achieve: Index_1, Index_2, index_3 ... But if this list is not the main part of the page, or the rest of the page has many rich elements, such as a large slider, then the whole page will blink badly, and a lot of resources have to be reloaded. So use AJAX requests to dynamically change the DOM.
However, the normal dynamic request does not change the URL, the user points to the next page, or a few pages, want to return to the previous page, may go to the browser's return key, so that the return time is not returned to the original view of the page, but the previous URL. For example, CCTV's news network is like this. Let's start with an AJAX request and analyze it in a complete case.
I did a demo.
First, write a request:
//Current pagevar pageIndex = 0;//Request functionfunctionmakerequest(PageIndex) {var request =NewXMLHttpRequest (); Request.onreadystatechange =StateChange;//Request two parameters, one is the current page, the other is the number of data per pageRequest.open ("GET", "/getbook?page=" + PageIndex + "&limit=4", true ); Request.send (nullfunction StateChange () { //if (request.readystate!== 4) { return// request succeeded if ( Request.status >= && request.status < 300 | | Request.status = = = 304var books = Json.parse (Request.responsetext); renderpage (books); } } }
When you get the data, render it:
functionRenderpage(books) {var bookhtml = "<table>" + "<tr>" + "<th> title </th>" + "<th> author </th>" + "<th> version </th>" + "</tr>"for (var i in Books) {bookhtml + = "<tr>" + "<td>" + books[i].book_name + "</td>" + "<td>" + books[i].author + "</td>" + "<td>" + books[i].edition + "</td>" + "</tr>" ; var section = document.createelement ("section" bookhtml; document.getElementById ( "book"). InnerHTML = bookhtml; }
This basic AJAX request is set up and then responds to the next page button:
function NextPage () { //The index of the page plus 1 pageindex++; // Resend Request and page load makerequest (pageIndex); }
In this case, if you do not do anything, you will not be able to play the role of browser back, Forward button.
If you can detect the user point back, forward button, you can do some articles. H5 is the addition of such an event window.onpopstate, when the user clicks the two buttons will trigger this event. But the light detects this event is not enough, but also to be able to pass some parameters, that is, to return to the previous page when you need to know the pageindex of the page. This is accomplished through the Pushstate method of history, where Pushstate (PageIndex) Saves the pageIndex of the current page and then returns to the page when it gets to this pageIndex. The parameters of the pushstate are as follows:
Window.history.pushState (state, title, URL);
Where the state is a object{}, used to hold the current page of data, title title does not have much effect, the URL is the URL of the current page, once the URL changes, the address of the browser address bar will also change.
So, in the NextPage function that requests the next page of data, add one more step:
function NextPage () { pageindex++; MakeRequest (pageIndex); // store data for the current page null, window.location.href); }
Then listen for the Popstate event:
If the user clicks back or Forward button function(event) { var page = 0//null) {page = Event.state.page; } makerequest (page); PageIndex = page;});
The state data is passed through the event so that pageindex can be obtained.
However, there are problems with this implementation, in the second page if you refresh the page, there will be confusion, as follows: First point to the next page to the second page, and then refresh the page, the first page, then the next page, the second page appears, the point returned when the problem, the display or the second page, not the first page expected, It is the first page until the point is returned again:
From the toolbar on the right, you can find that the pageindex is still 1 when the point is first returned. For this scenario, you need to analyze the history model as follows:
Can be understood as the operation of the history, the browser has a queue to hold access to the records, including each access to the URL and state data. Initially, the first pointer of the queue points to the position of page = 0, when the next page is executed, a pushstate is inserted, an element is injected into the queue, and the URL and state data of the element are recorded through the pushstate operation. It can be seen here that the most important function of the pushstate is to insert elements into the history queue, so that the browser's Back button is not the gray state, followed by the above-mentioned storage data. Point back, the team first pointer back to the location of page = 0, point forward and then forward to page = 1 position.
If you refresh the page in the location at page = 1, the model looks like this:
When the 2nd step is refreshed, the pageindex of the page reverts to the default value of 0, so page = 0 shows the first page of data, but the queue used by history has not changed. Then click on the next page, and then push an element to the queue, the queue has two pageindex 1 elements, so it must be two times to return to the location of page = 0, that is, the above described the situation of confusion.
According to the above analysis, this implementation is problematic, but the user is not in page = 0 location to refresh the pages, there will be more than a few times to return the button to return to the original page.
So in the refresh, the current page of the state data update, with Replacestate, replace the queue team first pointer data, that is, the current page data. The method is to replace the page when it is initialized:
NULL, WINDOW.LOCATION.HREF);
This model becomes:
But in fact, when users refresh, it is more desirable to display the current page, rather than back to the first page. One solution is to use the current page's window.history.state data, which is supported later by this property browser. When setting pageindex on page initialization, it is taken from history.state:
Null? 0:window.history.state.page;
The history.state in Safari is the data that was recently executed by Pushstate, so this approach can work in Chrome/firefox, but Safari won't work.
The second option is to use H5 's localstorage to store the current number of pages:
//Page initialization, fetch the current page first from Localstorage var pageIndex = Window.localStorage.pageIndex | | 0; functionNextPage () {//Add 1 to the index of the page and store it in LocalstorageWindow.localStorage.pageIndex = + +pageIndex; // Resend request and page load nullfunctionvar page = 0; if (event.state!== null ) {page =// Window.localStorage.pageIndex = page; });
Place all changes in the page pageindex, and put them in localstorage. This allows you to refresh the page by taking the pageindex of the current page.
The method above is to put the pageindex in the state parameter, and another way is to put it in the third parameter URL, that is, by changing the current page URL method. pageindex from the URL:
1//Current page2var pageIndex = Window.location.search.replace ("? page=", "" ") | | 0; 3 function nextPage () { 4 // index of the page plus 1 5 + +PageIndex; 6 // Resend Request and page load
7
makerequest (pageIndex); 8 window.history.pushState (null, null, "? page=" + pageIndex); 9}
Note that once the 8th line of Pushstate is executed, the address of the current URL will change.
It is important to note that although Window.history.length returns the number of elements in the current queue, it does not mean that the history itself is that queue, through the output of different browsers to History[i]:
You can see that the history is an array, which is to let the user get the history.length, the current length, but the content of the fill is indeterminate.
In addition to the use of history, but also with the help of a hash method, NetEase news is the use of such a method:
1//Current page2var pageIndex = window.location.hash.replace ("#page =", "") | | 0; function NextPage () {
4 MakeRequest (pageIndex); 5 Window.location.hash = "#page =" + Pageindex; 6 } 7 window.addeventlistener ("Hashchange", Function () { 8 var page = Window.location.hash.replace ("#page =", "") | | 0; 9 MakeRequest (page) ; 10});
For support, refer to Caniuse website: History IE10 and above support, hashchange support is better, IE8 and above all support.
Although Hashchange is a better supporter, history has the advantage of being able to pass data. It can be very useful for some complex applications, and history supports BACK/GO operations.
Reference:
Dive into html5:manipulating historyfor fun & Profit
Using H5 's history to improve the Ajax list request experience