H5 based history improved AJAX list request experience _ajax related

Source: Internet
Author: User

Rich information of the site will usually be paginated, at the point "next", many sites have adopted a dynamic request to avoid page refreshes. Although everyone is Ajax, but from a few small details can be distinguished from the pros and cons. A small detail is the ability to support the browser "back" and "forward" keys. This article discusses two ways to get the browser to back up and forward, or to let Ajax have the ability to return to the previous page or to the next page as if it were redirected to a new page.

Data implementation paging display, the simplest way is to add multiple page after the URL number, click "Next", let the page redirect to the new address of page+1. For example, Sina's news network is doing so by changing the URL to achieve: Index_1, Index_2, index_3 ... But if the list is not the main part of the page, or the rest of the page has many rich elements such as a lot of pictures, such as navigation is a big slider, then in this way, the entire page will flicker, and a lot of resources have to reload. So use AJAX requests to dynamically change the DOM.

But ordinary, dynamic requests don't change the Web site, users point to the next page, or click on the first page, want to return to the previous page, may go to the browser to return the 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 the AJAX request and analyze it in a complete case.

I did a demo.

First, write a request:

 Current first few pages
  var pageIndex = 0;
  Request functions function
  MakeRequest (pageIndex) {
    var request = new XMLHttpRequest ();
    Request.onreadystatechange = StateChange;
    The request passes two parameters, one is the current first page, the other is the number of data bars per page
    request.open ("Get", "/getbook?page=" + PageIndex + "&limit=4", true);
    Request.send (null);
    function StateChange () {
      //status code is 4, loaded, request complete
      if (request.readystate!== 4) {return
        ;
      }
      Request Success
      if (request.status >= && request.status < $ | | request.status = = 304) {
        var books = JS On.parse (request.responsetext);
        Renderpage (books);}}
  

Render after data is obtained:

  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> prev </button>" + 
      "<button onclick= ' nextPage (); ' > next page </button> ";
    var section = document.createelement.
    section.innerhtml = bookhtml;
    document.getElementById ("book"). appendchild (section); 
  

This basic AJAX request is set up and then responds to the next page button:

  function NextPage () {
    //Add index of page to 1
    pageindex++;
    Re-send the request and page load
    makerequest (pageIndex);
  }

In this case, if you do not do any processing, you will not be able to play the browser back, forward button role.

If you can detect the user point back, forward button, you can do some articles. H5 is the addition of an event window.onpopstate that triggers the event when the user clicks on the two buttons. But the light detects this event is not enough, but also have to be able to pass some parameters, that is to return to the previous page when you have to know the pageindex of the page. This can be achieved by history's Pushstate method, where Pushstate (PageIndex) Saves the pageIndex of the current page and returns to the page when it is retrieved. The pushstate parameters are as follows:

Copy Code code as follows:

Window.history.pushState (state, title, URL);

Where state is a object{}, used to hold the current page data, title title does not have much effect, URL for the current page URL, once changed this URL, browser address bar address will follow the changes.

So, in the NextPage function that requests the next page of data, add one more step:

  function NextPage () {
    pageindex++;
    MakeRequest (pageIndex);
    The data
    window.history.pushState ({page:pageindex}, NULL, WINDOW.LOCATION.HREF) that holds the current page; 
  

Then listen for the Popstate event:

  If the user clicks the Return or Forward button
  Window.addeventlistener ("Popstate", function (event) {
    var page = 0;
    Since the first page has no pushstate, there is no data to return to the first page, so it's time to Judge
    if (event.state!== null) {
      page = event.state.page;
    }
    MakeRequest (page); 
    PageIndex = page;
  });

State data is passed through the event so that pageindex can be obtained.


However, there is a problem with this implementation, and if you refresh the page on the second page, will occur as follows: First, click the next page to the second page, and then refresh the page, the first page, and then click the next page, the second page, the point returned when the problem, show or the second page, is not the first expected page, The first page is not until the return point:

From the toolbar on the right, you can see that the pageindex is still 1 when the point is returned for the first time. For this situation, you need to analyze the history model as follows:

Can be understood as the operation of the history, the browser has a queue to store the access records, including each visited URL and state data. At first, the queue's first pointer points to the location of page = 0, and the next page executes the pushstate, inserts an element into the queue, and records the URL and state data of the element through the pushstate operation. It can be seen here that the most important role of pushstate is to insert elements into the history queue, so that the browser's Back button is not the state of ash, followed by the above storage data. When the point is back, the team's first pointer steps back and points to the position of page = 0, where the point advances and points to page = 1.

If you refresh the page in the position of page = 1, the model looks like this:

In the 2nd step refresh, the page pageindex back to the default value of 0, so page = 0, display the first page of data, but history used by the queue has not changed. Then click on the next page, and give this queue to push an element, the queue has two pageindex 1 elements, so must be returned two times to return to page = 0 position, which is said above the disorder.

According to the above analysis, such an implementation is problematic, but the user is not in page = 0 of the location to refresh the page, there will be a need to return the button more than once to be able to return to the original page.

So in the refresh time, the current page of the state data update, with Replacestate, the queue team to replace the first pointer data, that is, the current page data. method is to replace the page when it is initialized:

Window.history.replaceState ({page:pageindex/* here is 0*/}, NULL, WINDOW.LOCATION.HREF);
So the model becomes:

But in fact, when users refresh the more hope is to display the current page, rather than back to the first page. One solution is to use the Window.history.state data from the current page, which is supported later by the property browser. When pageindex is set when the page is initialized, it is fetched from the history.state:

 
 

Safari's history.state is the latest to execute pushstate incoming data, so this approach works in Chrome/firefox, but Safari doesn't work.

The second option is to store the current number of pages using H5 localstorage:

 Page initialization, take the current first few pages from Localstorage
  var pageIndex = Window.localStorage.pageIndex | | 0;

  function NextPage () {
    //adds 1 to the index of the page and stores it in localstorage
    window.localStorage.pageIndex = ++pageindex;
    Re-send request and page load
    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 clicking Back or forward, you need to place the page on localstorage
    window.localStorage.pageIndex = page;
  };

Place all changes pageindex in the page at the same time to Localstorage. This way, when you refresh the page, you can take the pageindex of the current page.

The above method is to put the pageindex into the state parameter, there is another way to put it in the third parameter URL, that is, by changing the current page URL method. PageIndex from the Web site:

 Current first few pages
   var pageIndex = Window.location.search.replace ("? page=", "") | |;
   function NextPage () {
     //Add the index of the page
     ++pageindex;
     Re-send request and page load
     makerequest (pageIndex);
     Window.history.pushState (NULL, NULL, "? page=" + PageIndex);
   }

Note that once the pushstate of line 8th is executed, the address of the current URL will be changed.

One thing to note is that although Window.history.length returns the number of elements in the current queue, it does not mean that the history itself is the queue, through different browsers of the history[i] output:

You can see that history is an array, and its function is to let the user get history.length, the current length, but the content of the fill is indeterminate.

In addition to the use of history, there is the use of hash method, NetEase news is using this method:

   Current first few pages
   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);
   

About support, refer to Caniuse website: History IE10 and above support, hashchange support is good, IE8 and above all support.

Although Hashchange support is good, the advantage of history is that data can be transmitted. Some complex applications may play a significant role, while history support for back/go operations.

The above article about H5 's history improves the AJAX list request experience, hope everybody likes.

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.