Improved ajax List request experience based on h5. h5historyajax list

Source: Internet
Author: User

Improved ajax List request experience based on h5. h5historyajax list

Websites with rich information are usually displayed by page. When you click "next page", many websites use dynamic requests to avoid page refresh. Although we all use ajax, the advantages and disadvantages can be distinguished from some small details. A small detail is whether the browser supports the "backward" and "Forward" keys. This article discusses two methods that allow the browser to move back and forward, or give ajax the ability to return to the previous page or forward to the next page just like redirecting to a new page.

The simplest way to display data by page is to add the number of pages after the URL and redirect the webpage to the new address of page + 1 by clicking "next page. For example, Sina's news network does this. By changing the website address, you can achieve: index_1, index_2, index_3 ....... However, if the list is not the main part of the page, or the other part of the page has many images and other rich elements, such as navigation is a large slider, then use this method, the whole page will flash badly, and many resources have to be reloaded. Therefore, use ajax requests to dynamically change the DOM.

However, normal dynamic requests do not change the URL. When a user clicks the next page or the page number, he or she wants to return to the previous page, he or she may click the browser's return key, in this way, the returned result is not returned to the previously viewed page, but to the previous website. For example, the CCTV News Network is like this. The following is a complete case study of ajax requests.

Made a demo

First, write a request:

// Current page var pageIndex = 0; // request function makeRequest (pageIndex) {var request = new XMLHttpRequest (); request. onreadystatechange = stateChange; // two parameters are required for the request, one for the current page and the other for the number of data entries per page. open ("GET", "/getBook? Page = "+ pageIndex +" & limit = 4 ", true); request. send (null); function stateChange () {// the status code is 4, indicating loaded. The request is complete if (request. readyState! = 4) {return;} // if (request. status> = 200 & request. status <300 | request. status = 304) {var books = JSON. parse (request. responseText); renderPage (books );}}}

After obtaining the data, perform rendering:

Function renderPage (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>";} bookHtml + = "</table> "; bookHtml + = "<button> previous page </button>" + "<button onclick = 'nextpage (); '> next page </button>"; var section = document. createElement ("section"); section. innerHtml = bookHtml; document. getElementById ("book "). appendChild (section );}

A basic ajax request is initiated, and then the "next page" button is returned:

Function nextPage () {// Add 1 pageIndex ++ to the index of the page; // re-send the request and load the makeRequest (pageIndex );}

At this point, the browser's return and Forward buttons cannot be used without any processing.

If you can detect that the user has clicked the backward and forward buttons, you can write some articles. H5 adds the window. onpopstate event. When the user clicks the two buttons, the event will be triggered. However, it is not enough to detect this event. You must pass some parameters, that is, you must know the pageIndex of the page when you return to the previous page. This can be achieved through the pushState method of history. pushState (pageIndex) stores the pageIndex of the current page and obtains the pageIndex when returning to this page. The pushState parameters are as follows:

Copy codeThe Code is as follows:
Window. history. pushState (state, title, url );

The state is an object {}, which is used to store data on the current page. The title does not have much effect. The url is the url of the current page. Once this url is changed, the address in the browser's Address Bar also changes.

Therefore, in the nextPage function that requests data on the next page, add one more step:

Function nextPage () {pageIndex ++; makeRequest (pageIndex); // store the data window of the current page. history. pushState ({page: pageIndex}, null, window. location. href );}

Then listen to the popstate event:

// If the user clicks the return or forward button window. addEventListener ("popstate", function (event) {var page = 0; // No data is returned to the first page because the first page does not have pushState, therefore, you have to determine if (event. state! = Null) {page = event. state. page;} makeRequest (page); pageIndex = page ;});

The state data is passed in through the event to obtain the pageIndex.


However, there is still a problem with this implementation. If you refresh the page on the second page, it will be disordered, as shown below: first, click the next page to the second page, then refresh the page, and the first page appears, click the next page, and the second page appears. If a problem occurs when you click return, the page is displayed as the second page. It is not the expected first page until you click return again:

From the toolbar on the right, we can find that the pageIndex obtained at the first return point is still 1. In this case, you need to analyze the history model as follows:

The browser has a queue for storing access records, including each access URL and state data. At the beginning, the first pointer of the queue points to the position of page = 0. When the next page is clicked, pushState is executed and an element is inserted in the queue, at the same time, the url and state data of this element are recorded through the pushState operation. Here we can see that the most important role of pushState operations is to insert elements to the history queue, so that the browser's back button is not in the gray state, followed by the above-mentioned data storage. When the point is backward, the first pointer of the team points back to the position where page = 0, and advances to the position where page = 1.

If you refresh the page at page = 1, the model looks like this:

When the page is refreshed in step 1, the page's pageIndex is restored to the default value 0, so page = 0 shows the first page of data, but the queue used by history has not changed. Then, when the next page is clicked, an element is pushed to the queue. This queue has two elements with pageIndex 1. Therefore, the queue must be returned twice to return to the position where page = 0, that is, the disorder mentioned above.

According to the above analysis, this implementation is problematic. First, the user does not refresh the page at the position where page = 0, the page appears after you click the return button multiple times to return to the original page.

Therefore, you must update the state data on the current page during refresh. replaceState is used to replace the data of the first pointer of the queue, that is, the data on the current page. The method is to replace the following during page initialization:

Window. history. replaceState ({page: pageIndex/* here 0 */}, null, window. location. href );
In this way, the model becomes:

However, when you refresh the page, you want to display the current page instead of returning to the first page. One solution is to use the window. history. state data of the current page, which is supported by the browser later. When pageIndex is set during page initialization, It is retrieved from history. state:

 

var pageIndex = window.history.state === null ? 0 : window.history.state.page; 

History. state in safari is the data passed in by pushState recently executed. Therefore, this method works in chrome/firefox, but safari does not work.

The second method is to use the localStorage of h5 to store the current page number:

// Page initialization. Take the current page and obtain var pageIndex = window from localStorage. localStorage. pageIndex | 0; function nextPage () {// Add 1 to the index of the page and store it in localStorage window. localStorage. pageIndex = ++ pageIndex; // resend the request and load the makeRequest (pageIndex); window. history. pushState ({page: pageIndex}, null, window. location. href);} window. addEventListener ("popstate", function (event) {var page = 0; if (event. state! = Null) {page = event. state. page;} makeRequest (page); // when you click return or forward, you need to put the page in localStorage window. localStorage. pageIndex = page ;});

Place all the places on the page that change pageIndex and put it to localStorage. In this way, you can obtain the pageIndex of the current page when refreshing the page.

The above methods put pageIndex into the state parameter, and put it in the third parameter url, that is, by changing the current page url. PageIndex:

// Current page var pageIndex = window. location. search. replace ("? Page = "," ") |; function nextPage () {// Add + pageIndex to the index of the page; // resend the request and load makeRequest (pageIndex) to the page ); window. history. pushState (null, null ,"? Page = "+ pageIndex );}

Note: Once the pushState of Row 3 is executed, the current URL address will change.

Note that window. history. although length returns the number of elements in the current queue, it does not mean that history itself is the queue. The output of history [I] through different browsers:

It can be seen that history is an array, which enables users to get history. length, the current length, but the filled content is uncertain.

Besides using history, Netease news also uses the hash method:

// Current page var pageIndex = window. location. hash. replace ("# page =", "") |; function nextPage () {makeRequest (pageIndex); window. location. hash = "# page =" + pageIndex;} window. addEventListener ("hashchange", function () {var page = window. location. hash. replace ("# page =", "") |; makeRequest (page );});

For support, refer to the caniuse Website: history IE10 and above. hashchange supports better, and IE8 and above support.

Although hashchange supports a lot, history has the advantage of being able to transmit data. It may play a major role in some complex applications, and history supports back/go operations.

In this article, we hope that h5's history will improve the ajax List request experience.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.