A few years ago, the rise of Ajax to the internet brought new vitality, but also make the user experience has a qualitative leap, users do not have to refresh the page to obtain new data, and the page in a more interactive form for users to show the view, it can be said that the contribution of this change to the development of the Internet is unprecedented.
However, with the large-scale application of Ajax, more and more developers are beginning to notice the problem, because the Ajax view is displayed in the page without a refresh, which means that after the user has done a series of actions, the page URL is not any change, The results of these operations are naturally not preserved, and when the user accesses them again, the data they want to present cannot be reproduced.
For example, we browse an album on a photographic website, click on the first image will dynamically pop up a large picture of the frame, you can better browse the picture, when you see a picture of their own, eager to share this picture, so the current URL published, but our friends click to find, See only the original album, and did not pop up the big picture frame, let alone we want to share the picture, is not very disappointed. Because of this, this page can not be accurately crawled by the search engine, SEO can not be optimized, the user's accessibility is also greatly discounted.
To solve this problem, the developer tries to use the hash in the URL to improve accessibility (the hash attribute is a readable, writable string that is the anchor part of the URL (starting with the # number), and some browsers begin to provide hash-related event support, Some well-known sites and the search engine agreed to use a certain rules to crawl the site page, but this is not a standard technology, or inevitably there are many problems, developers also look forward to a standardized perfect solution, to solve this problem completely.
Fortunately, the HTML5 in the history API to developers with New Hope, it is very good to support the URL-based page no refresh operation, but also make SEO optimized to solve the perfect, no doubt, will be the future of the Web World API standards, More and more developers will use it to develop their own applications.
So today, let's talk about the technology associated with history.
To be able to better articulate this new technology, we chose to use an example program to get started. As shown, we show three small pictures, click on any one, will pop up a large preview, and then you can toggle the preview image back and forth:
This program for everyone should be said to be relatively simple, when you click on a small map, will place a large map of the page elements displayed, pictures and profiles to show the information corresponding to the small map, it is very easy to switch the operation of the preview picture.
This is the traditional Ajax operation, and this operation has a very serious flaw, we can not record the current view of the picture information, if the back of the small figure has hundreds of, when we browse to a certain piece, feel very good, want to send it to friends, also may want to save themselves, this time we will find that, The URL does not have any information about this image, and copying the address bar will have no effect.
So we desperately need to include the information generated by the user operation in the URL, this time the history API comes in handy, and he provides a way to update the URL without refreshing the page. Here's a look at the main two methods:
History.pushstate (stateobj, title, URL);
This method will put a record into the history stack of the current session, Stateobj is a user-defined object, used to record some useful data, title as the name implies is the header information, the third parameter is to put the URL information. For example, when we click on the second picture, we can execute History.pushstate ({id:2}, ' Img:2 ', '? preview=2 ');
History.replacestate (stateobj, title, URL);
This method is similar to Pushstate, except that, after performing this operation, the browser replaces the records in the session history stack instead of adding them, which is more appropriate in a particular scenario.
We're here to combine examples to explain how to manipulate history.
As you can see, the page initializes with three small images, and when you click on any of the thumbnails, a preview is displayed, and the basic frame of the page is as follows:
<!DOCTYPE HTML> <HTML> <Head> <title>History</title> <Linkrel= "stylesheet"type= "Text/css"href= "Css/main.css"> </Head> <Body> <ulID= "Gallery"> <Li> <imgsrc= "Img/1.jpg"Data-id= "1"/> </Li> <Li> <imgsrc= "Img/2.jpg"Data-id= "2"/> </Li> <Li> <imgsrc= "Img/3.jpg"Data-id= "3"/> </Li> </ul> <DivID= "Shadow-layer"class= "For-dialog"></Div> <DivID= "Preview-panel"class= "For-dialog"> <imgID= "Preview-img"/> <DivID= "Preview-info"></Div> <DivID= "Preview-close"class= "Preview-button">Close</Div> <DivID= "Preview-prev"class= "Preview-button"><</div> <DivID= "Preview-next"class= "Preview-button">></Div> </Div> </Body> <Scripttype= "Text/javascript"src= "Js/jquery.js"></Script> <Scripttype= "Text/javascript"src= "Js/main.js"></Script> </HTML>
Then, when the page is initialized, we need to bind the events to some DOM elements, just like this:
//Click the thumbnail to start the preview mode$ (' #gallery img '). Click (function() {Preview (parseint ($ ( This). attr (' Data-id '))); }); //Close the Preview view$ (' #preview-close '). Click (function() { $('. For-dialog '). Hide (); Window.history.back (); }); //Click to preview the previous photo$ (' #preview-prev '). Click (function() {Switchprev (); }); //Click to preview the next photo$ (' #preview-next '). Click (function() {switchnext (); });
You can see a few bound events, click the thumbnail will trigger the preview mode, and then click the Close button in the preview, will hide the preview box, and call the history of the back function, we will introduce later, the last is two toggle button events, respectively, will switch to the previous or next big picture. We notice that when the small graph is clicked, a function called preview is called, and this function is exactly what we want to say, the code is as follows:
functionPreview (ID, isswitch) {$ ('. For-dialog '). Show (); //get the corresponding data information vardata =Getpreviewdatabyid (ID); $(' #preview-img '). attr (' src '), data.img); $(' #preview-info '). HTML (data.info); //record the ID of the current preview image and use it when switching back and forth$ (' #preview-panel '). attr (' Data-prview-id '), id); varStateobj ={Id:id}; varOperation = Isswitch? ' Replacestate ': ' Pushstate '; //put a record in the history stack or replace a recordWindow.history[operation] (stateobj, ' img: ' + ID, '? preview= ' +ID); }
The preview function above is primarily responsible for several important tasks, first displaying the previews box, then obtaining data information based on the data ID, and finally manipulating the history object. In real-world development, Getpreviewdatabyid functions are mostly done in Ajax, and this is the time to put the following logic inside the callback function. At the end of the preview function, we put or replace an object containing ID information into the history, changing the URL, putting it in or replacing it, depending on whether the preview is switched back and forth, we'll explain it in more detail later. Note that this time, although the URL has changed, the page does not refresh. Let's compare the effects before and after clicking on the second small image as an example:
As you can see, the address bar has changed, which is actually the result of our call to the Pushstate function:
Window.history.pushState ({id:2}, ' Img:2 ', '? preview=2 ');
Another point to note is that the third parameter is the new URL address, according to the official documentation, it can be a relative address, or it can be an absolute address, so we can also choose to use absolute address, as follows, the effect is the same:
Window.history.pushState ({id:2}, ' Img:2 ', ' http://localhost/history/?preview=2 ');
In the preview function parameter list above, there is a isswitch parameter, if the function is called to specify this parameter, then it will call Replacestate instead of pushstate, which is why, here is to explain.
Remember when we turned off the button bindings for the top right corner of the preview box, in addition to hiding the preview, we also called the history's back function, in fact, we were going to use this function to pop the historical record from the history stack and then restore the URL to the pre-preview state. Well, if we frequently switch to the next or previous in the preview, there will be a lot of records in the history stack, it is obviously not easy to go back to the initial state, we do not have to keep so many history, so when the user toggles the preview map before and after the Just call Replacestate to replace the record in the current history stack, if we click the Toggle button on the right, it should be:
Window.history.replaceState ({id:3}, ' Img:3 ', '? preview=3 ');
To invoke the Replacestate function, we need to pass in a Isswitch parameter when we execute the preview function, and we'll see how it's called:
// Preview the next one function Switchnext () { /// the next ID is calculated based on the current ID var currid = parseint ($ (' # Preview-panel '). attr (' Data-prview-id ')); Currid++ ; > 3 && (currid = 1); true ); }
Here are two to explain the stack structure before and after the switchover:
This way we can guarantee that there is only one record in the history stack, and immediately revert to the previous view when the Preview box is closed.
And the forward switch is the same, the code is as follows:
// Preview the previous one function Switchprev () { /// based on the current ID, calculate the previous ID var currid = parseint ($ (' # Preview-panel '). attr (' Data-prview-id ')); Currid--; < 1 && (Currid = 3); true ); }
Here, I think we all know how to manipulate the history stack to change the URL, then we have to ask not only, if the current URL to revisit the site, how to restore the view before the shutdown, in fact, this is a basic operation, only need to be in the OnLoad function to get the corresponding parameters, Then call the preview function, as shown in the code:
//gets the ID of the current preview image from the URLfunctionGetcurrpreviewid () {varSearch =Location.search; if(!search)return-1; varparams = {}; varKeyValues = search.substring (1). Split (' & '); Keyvalues.foreach (function(item) {varParts = item.split (' = ')); params[parts[0]] = parts[1]; }); if(!params[' preview ')return-1; returnparams[' Preview ']; } //When the page loads, if there is a preview message in the URL, remove and thenWindow.onload =function() { varID =Getcurrpreviewid (); if(ID < 1 | | ID > 3)return; Preview (ID); };
In fact, we have already explained the whole process, but there is an important event that we have not touched, that is the Onpopstate event under window, when the user clicks the Back button or the Forward button, or when our program executes History.back (), History.forward (), History.go (), triggers this event, which captures the state of the current history stack after these operations have been completed, and we can use this information to do further work. So let's do an experiment and see how the Onpopstate event is triggered:
function (e) { console.log (' e.state: ', e.state); };
Within this event function, we print the state object in the event object, which is actually the object we put in when we execute the Pushstate function, and below we do the following in the console to see the effect:
, we put in two records, when backward or forward, will execute to the Onpopstate event function, and can get to the current state object information, if our picture preview function needs to record each step of operation, Then we can get the image ID that we need to present in the Onpopstate event function, then call the preview function directly.
Finally, it should be noted that some browsers do not support the history API very well, so we'd better judge the browser's support situation:
var in Window.history;
Here, about the history of the relevant knowledge and application is basically over, I hope you can carefully understand its application, and practice, and finally hope that we can well master and apply to future projects.
History of new features of HTML5