This article mainly introduces how to implement the forward and backward functions of browsers without refreshing JavaScript. This article provides HTML5 solutions and methods for writing old browsers. For more information, see backbone, to learn and understand backbone, you must first understand spa. To understand spa, you must first understand how a single page application does not refresh the page and change the url.
Compared with page jumps, AJAX can greatly improve the user's browsing experience. It is quite pleasant to see the white screen between page switches. However, many early AJAX applications do not support the browser's forward and backward operations. This causes users to immediately return to their initial positions no matter where they are viewed on the website, in addition, you cannot switch the browsing history using the browser's forward and backward buttons.
It is easy to solve the first problem. You only need to use cookies or localStorage to record the application status. When you refresh the page, read the status and send an ajax request to change the page. But the second problem is very troublesome. Let's talk about the solutions of modern browsers first.
HTML5 Solution
To understand how HTML5 implements moving forward and backward, you must first understand the history object and location object.
History Object
History Object Attributes
1. length: return the number of URLs in the browser history list. Each time you access a page in the current tag, this number is increased by 1. The specific URL content is invisible for privacy reasons.
2. state: the object associated with the current URL. It can only be added or modified through pushState and replaceState. We can use it to store url-related information.
History Object Method
1. history. back ()
This method has no parameters. When triggered, it will return to the previous page, which is equivalent to clicking the back button of the browser.
2. history. forward ()
This method has no parameters. If this method is triggered, the browser's forward button is clicked.
3. history. go (number)
This method accepts an integer parameter, history. go (-1) is equivalent to a back page, history. go (1) is equivalent to the previous page, history. go (0) refreshes the current page.
4. history. pushState (state, title, url)
The key to changing the url without refreshing the page is that this method changes the location. href of the current page and modifies the current history. state object. After the command is executed, the value of history. length increases by 1. This method accepts three parameters,
1. state: the object related to the current URL.
2. title: the title of the page, which is ignored by all browsers. To change the title, use document. title.
3. url: a url in the same domain as the current page. location. href is changed to this value.
5. history. replaceState (state, title, url)
This method is the same as above, but it does not change history. length. It only modifies history. state and location. href.
Note that the third parameters pushState and replaceState cannot be cross-domain and do not trigger the browser's popstate event and onhashchange event (test in chrome33 ).
Location object
In addition to clicking the forward/backward button and the history event, you can also change the Url by using the location method and modifying the location attribute:
Location object attributes (read/write ):
1. host: domain name + port number
2. hostname: Domain Name
3. port: port Number
4. protocol: protocol
5. href: complete path
6. origin: Protocol + domain name + Port
7. hash: the URL starting)
8. pathname: Document path + document name
9. search :(?) Subsequent content
You can change location. href or location. hash to avoid refreshing.
Location object method:
1. assign: changes the url value and adds the current url to the history record. history. length will increase by 1. Location. assig ('#' + x) changes the url but does not refresh the page.
2. reload: refresh the page.
3. replace: Change the url value, but the value of history. length remains unchanged. The usage is the same as assign.
Popstate event
When the url changes, for example, the user clicks the forward/backward button, history. go (n) (n is not equal to 0), location. hash = x (x is not equal to the current location. hash) will trigger this event. You can use it to listen to URLs for various functions.
The Code is as follows:
Window. onpopstate = function (){
// Do something
}
Onhashchange event
Changing the hash value triggers the popstate event, but triggering the popstate event does not necessarily trigger the onhashchange event. Tested:
1. Changing the hash value but changing the location. pathname will trigger the onhashchange event, for example, history. pushState (",", '# abc ');
2. Changing the hash and location. pathname together will not trigger, for example, history. pushState (",", 'a # abc ');
Old browsers
The old browser does not support pushState and replaceState, so the way to listen for url changes through popstate (in fact, this method is not supported) cannot be achieved. You can only change the content after the url # To achieve no refreshing, but they do not support onhashchange, therefore, the changes to the url are indifferent (except that the page will scroll to the location of the corresponding page id ). You can only make a big offer: round-robin, start a setInterval to listen to the url value. Like this:
The Code is as follows:
Var prevHash = window. location. hash;
Var callback = function (){...}
Window. setInterval (function (){
If (window. location. hash! = PrevHash ){
PrevHash = window. location. hash;
Callback (prevHash );
}
},100 );
Of course, this writing is very frustrating. If you do not consider changing the hash by clicking the tag with the id on the page, you can use the design mode to elegantly implement the listening url. For example, in the classic observer mode, a class is used to implement the function of changing the hash, and then all the classes (observer) that want to listen to url changes subscribe to this (observer) class.
The Code is as follows:
// Change the url class
Function UrlChanger (){
Var _ this = this;
This. observers = [];
// Add an observer
This. addObserver = function (obj ){...}
// Delete the observer
This. deleteObserver = function (obj ){...}
// Notify the observer
This. _ policyobservers = function (){
Var length = _ this. observers. length;
Console. log (length)
For (var I = 0; I <length; I ++ ){
_ This. observers [I]. update ();
}
}
// Change the url
This. changeUrl = function (hash ){
Window. location. hash = hash;
_ This. _ policyobservers ();
}
}
// Listener
Function oneOfObservers (){
Var _ this = this;
This. update = function (){...}
}
// Implementation
Var o1 = new UrlChanger ();
Var o2 = new oneOfObservers ();
O1.addObserver (o2 );
O1.changeUrl ('fun/arg1/arg2 /');
// O2 has do something...