【 Making wheels 】 It is a common method for the author to learn and understand some complicated code structures , It's slow , But the effect is better than you read a dozen related articles . For known API Methods self written implementation , Encounter the part that oneself cannot reappear again pertinently go to look up data , Finally, when you learn the official code again , You will understand the value of doing so , one fine day , You will also be able to write master code .

One . Front end routing

The most popular page model in modern front end development , Nothing more SPA
Single page application architecture . Single page application means that the application has only one main page , Through dynamic replacement DOM Content and synchronous modification url address , To simulate the effect of multi page applications , The function of switching pages is directly completed by the foreground script , Instead, the front end is only responsible for the display after rendering . Front end Troika
Angular,Vue,React All of them are based on this model .SPA Can simulate the effect of multi page application , Thanks to its front-end routing mechanism .

Front end routing , As the name suggests, it is a state manager for different front-end pages , Can not send requests to the background and directly through the front-end technology to achieve the effect of multiple pages .angularjs Medium ui-router
,vue Medium vue-router, as well as react Of react-router They are the concrete realization of this function .

Since the front-end routing is so powerful , You have to study it .

Two . Two realization methods and their principles

In the common routing plug-ins, both methods are supported and can be switched , for example angularjs1.x From the Hash Mode switch to H5 pattern :
$locationProvider.html5Mode(true);
Switch to HTML5 Routing mode of , Mainly used to avoid url Address contains # And the problems caused by it .

1.HashChange

1.1 principle

HTML Page through the anchor location principle can be no refresh jump , After triggering url There will be more in the address # + 'XXX' Part of , At the same time in the global window Trigger on object hashChange
event , This happens when the page anchor hash changes to a preset value , Trigger the corresponding page through the code DOM change , You can implement the basic routing , Based on anchor hash
The routing is intuitive , It is also the most commonly used method in general front-end routing plug-ins .

1.2 application

Let's take a look at an example , When you click angularjs When the , You can see that the console prints out the corresponding information .



2.HTML5 HistoryAPI

2.1 principle

HTML5 Of History API For browser's global history Extension method of object addition . It is generally used to solve the problem ajax The problem that the request cannot return to the state before the request through the back button .

stay HTML4 in , Already supported window.history Object to control page history jump , Common methods include :

* history.forward(); // A step forward in history
* history.back(); // Step back in history
* history.go(n): // Jump in history n step ,n=0 To refresh this page ,n=-1 To go back one page .
stay HTML5 in ,window.history Object has been extended , New API include :

* history.pushState(data[,title][,url]);// Append a record to the history
* history.replaceState(data[,title][,url]);// Replaces the current page's information in history .
* history.state;// Is an attribute , You can get the state information .
* window.onpopstate
;// It's an event , Click the browser Back button or js call forward(),back(),go() Time triggered . You can pass in a event object ,event.state Is passed pushState() or replaceState() Method data parameter .
2.2 application

When a browser visits a page , The status information of the current address is pushed into the history stack , When calling history.pushState() Method to push a new one into the history stack state
after , The pointer at the top of the history stack points to the new state Of . Its function can be simply understood as Pretend it's changed url Address and jump , Unless the user clicks the browser forward , Back off
, Or explicitly HTML4 The method of operating history stack in , Otherwise, it will not trigger the global popstate event .

In the following example , Click the navigation button , You can see url The address bar has changed , And the response of the console is printed .



3.hash and history API contrast

contrast hash route History API route
url character string ugly normal
Naming restrictions Usually only in the same document Make a change url The address can be defined by itself , As long as it is under the same domain name , More freedom
url Change of address It will change It can change , It can be left unchanged
State saving No built-in method , The status information of the page needs to be saved separately Custom information can be attached when the page information is pushed into the history stack
Parameter transfer capability suffer url Limit of total length , Custom information can be attached when the page information is pushed into the history stack
practicability It can be used directly Usually, the server needs to modify the code to match the implementation
compatibility IE8 above IE10 above
Three . Build a simple front-end routing plug-in

Making wheels , Not to put it in your car , It's a choice when you're driving in the wilderness and the wheels are out of order .

Next, let's implement a plug-in for front-end routing ~

3.1 be based on Hash Front end routing plug-in for myHashRouter.js

What we want to achieve is :

* 1. introduce MyHashRouter.js library
* 2. adopt when() Method to define several different routing states
* 3. adopt init() Method to start the routing function
* 4. Front end route switching through click navigation
Write it first js skeleton , As shown in the figure :
;(function() { function Router() { // Record route jump history this.historyStack = [];
// Record registered route information this.registeredRouter = []; // Jump item when route matching fails this.otherwiseRouter = {
path: '/', content: 'home page' } } /* * Start routing function */ Router.prototype.init =
function() { } /* * binding window.onhashchange Event callback function */
Router.prototype._bindEvents = function() { } /** * Route registration method */
Router.prototype.when = function(path, content) { } /** * Determine whether the newly added route already exists */
Router.prototype._hasThisRouter = function(path) { } /** * The specified address when the route does not exist */
Router.prototype.otherwise = function(path, content) { } /** *
Route jump method , Can be used for jump routing when actively called */ Router.prototype.go = function(topath) { } /** *
Used to render the corresponding routing information to the page , Realize route switching */ Router.prototype.render = function (content) { } var
router = new Router(); // Expose the interface to the global window.$router = router; })();
After writing the routing plug-in , We are here demo The library is introduced in , Then use the when() Method to register several routing addresses , Reuse init() Method to start routing , The script part code is as follows :


effect :
Run the router-demo-hash.html, Click the navigation button , You can see url Synchronous changes to address bar and content area .


3.2 be based on History API Front end routing plug-in for myHistoryRouter.js

because History API Less than is not supported IE10 The following versions of the browser ( Most other modern browsers basically support it ), So we're here init()
When the method is started, the usability is judged first , Basic code framework and based on Hash The routing plug-ins are consistent . The implementation of each method is not difficult to write , I will not repeat it here , The author's own code implementation is attached
myHashRouter.js in , The level is limited , For reference only .


3.3 Integration description

For ease of understanding , In this example, the two patterns are written separately , If it is the development of plug-in library , It can be imitated ui-router Add one more html5mode() Methods , stay init()
Method to start routing , Generate different instances of routing plug-ins according to the parameters passed , In other words, we often say that the factory mode can be realized .

Four . Postscript

* Making wheels is a good way to learn , Although the wheels made by ourselves are very simple , But it helps to understand the underlying principles of the tool .
* This example only writes the basic skeleton of a routing tool , Real routing tools need to do a lot of function extension , The complexity of individual functions will also be high , For example, regular matching of paths , Lazy loading , Composite view , nested view ,
Route animation and so on , Interested partners can learn and expand on the framework provided in this example .
* Appendix description :
* index_h5history.html —— history API Basic usage demonstration demo
* index_hashchange.html —— hashchange Basic usage demonstration demo
* router-demo-hash.html —— Cited myHashRouter.js Of demo
* myHashRouter.js —— Self developed hash Simple routing plug-in
* router-demo-hash.html —— Cited myHashRouter.js Of demo
* myHistoryRouter.js —— Self developed historyAPI Simple routing plug-in for
* router-demo-history.html —— Cited myHistoryRouter.js Of demo