front end: Make Web Site a single page app spaObjective
I do not know if you have found, such as GitHub, Baidu, Weibo and other such major stations, have no longer use the ordinary a tag to do jump. Most of them use AJAX requests instead of the a tag's default jump, and then use HTML5 's new API to modify the URL, which you can find in the F12 's network panel.
This technology does not have a special standard of scientific name, everyone is called pjax, meaning Pushstate + Ajax. This is not entirely accurate, because there are hash + Ajax methods, but for convenience, we are collectively referred to as Pjax.
Why do you do this?
Pjax is a good solution and you have plenty of reasons to use it:
- You can smooth transitions between page transitions, adding loading animations.
- You can pass data between pages, without relying on URLs.
- You can select a retention state, such as a music web site, to switch pages without stopping the song.
- All tags can be used to jump, not just a tag.
- Avoid the repeated execution of public JS, such as the need not to open each page to determine whether to log on and so on.
- Reduce the volume of requests, save traffic and speed up page response.
- Smooth downgrade to the lower version of the browser, will not affect the SEO.
How does it work?
The principle of pjax is very simple.
1. Intercept the default jump action for the a tag.
2. Use Ajax to request a new page.
3. Replace the returned HTML with the page.
4. Use HTML5 's history API or URL hash to modify the URL.
HTML5 History API
Let's see what HTML5 has added to the history:
History.pushstate (state, title, URL)
The Pushstate method adds the current URL to the history, and then modifies the current URL to the new URL. Please note that this method only modifies the URL display of the address bar, but does not make any requests. It is based on this feature that we implement Pjax. It has 3 parameters:
- State: You can put any data you want, and it will be appended to the new URL as a supplement to the information on that page.
- Title: As the name implies, is document.title. However, this parameter does not currently work, and the browser will now choose to ignore it.
- URL: The new URL, which is the URL you want to display on the address bar.
History.replacestate (state, title, URL)
The Replacestate method is similar to Pushstate, except that pushstate adds the current URL to the history, modifies the URL, and replacestate simply modifies the URL without adding a history.
Window.onpopstate Events
In general, popstate events are triggered whenever a URL changes. However, if you call pushstate to modify the URL, the event will not be triggered, so we can use it as the browser's forward and backward event. The event has a parameter, which is the first parameter state of the Pushstate method above.
An example:
Here we take daipig as an example, open Daipig, the address bar is http://www.daipig.com. Next Open the F12 Console and enter:
history.pushState({ a: 1, b: 2 }, null, "http://www.daipig.com/abcdefg");
It can be found that the URL has become the URL we entered, but the page has not been refreshed and no requests have been made. Now, with the input history.state, we can see the first parameter state we just passed.
Then click Back, the URL will return to www.daipig.com, the same is not refreshed. It's just that when you're back, it triggers the Window.onpopstate event.
Detailed documentation can be found in mdn:https://developer.mozilla.org/zh-cn/docs/dom/manipulating_the_browser_ ...
How to complete the implementation of Pjax?
The principle of pjax has already been said, not complicated. I have implemented a rough Pjax library that has been able to meet a lot of needs, and if you are interested, you can help improve the code on GitHub. The address is: Https://github.com/Coffcer/coffce-pjax.
The complete code is on GitHub, and here we talk about some of the areas that need attention.
Match Selector
To implement Pjax, there is a need to match selectors inevitably. You need to determine whether the currently clicked element matches the specified selector. Here I give a solution that is compatible to IE8:
Determine if element matches selector selector
function Matchselector (element, selector) {
var match =
Document.documentElement.webkitMatchesSelector | | Document.documentElement.mozMatchesSelector | |
Document.documentElement.msMatchesSelector | | Compatible with IE8 and the following browsers
function (selector, Element) {
This is a good way, but IE8 even indexof not support
Return Array.prototype.indexOf.call (Document.queryselectorall (selector), this)!==-1;
if (element.tagname = = = Selector.touppercase ()) return true;
var elements = Document.queryselectorall (selector),
length = Elements.length;
while (length--) {
if (elements[length] = = = this) return true;
}
return false;
};
Overriding the function itself, using closures to keep the match function, without having to judge compatibility every time
Matchselector = function (element, selector) {return Match.call (element, selector);}; return Matchselector (element, selector);
}
// 验证一下
matchSelector(document.getElementById("abc"), "#abc"); // true
matchSelector(document.querySelector("a"), "p"); // false
In modern browsers, it is preferable to use the native Matchesselector method to judge the result set of the loop Document.queryselector in IE8 and below, and then compare it in turn.
This method takes advantage of closures and then rewrites itself, only the first call to determine which prefix to execute which method, followed by a call to the closure of the match function.
What about browsers that don't support HTML5 pushstate?
IE6 to IE9 is not support pushstate, to modify the URL, can only take advantage of the URL hash, which is the # number.
You can find a website to try, add the # number and any content after the URL, the page will not be refreshed. Clicking Back now will only return to the previous # and will not refresh.
Then we just change the pushstate (new URL) to Localtion.hash = new URL, the Onpopstate event to Onhashchange event can be compatible with IE.
QQ Music, NetEase Cloud Music is the use of this way.
Ready-made libraries
Https://github.com/Coffcer/coffce-pjax, welcome PR and Star.
Front end: Make Web Site a single page app Spa