Awesome
spa-history
A HTML5 history library for single-page application.
Install
npm install spa-history
Constructor
PathHistory
import { PathHistory } from 'spa-history'
const history = new PathHistory({
// path of base directory. defaults to ''
// If you want the root path doesn't contain ending slash,
// you can set the base without ending slash, like '/app'
base: '/app/',
/*
beforeChange() will be called before location change.
Arguments:
to: A normalized location object. The location will be changed to.
from: A normalized location object. The current location.
action: String. What action triggered the history change.
push: history.push() is called.
replace: history.replace() is called.
pop: user clicked the back or forward button, or history.go(), history.back(), history.forward() is called, or hash changed.
init: "to" is the initial page, at this stage, "from" is null.
dispatch: history.dispatch() is called.
Returns:
true | undefined: The navigation is confirmed.
false: Prevent the navigation.
null: Do nothing.
path | location object: Redirect to this location.
You can override the history manipulate action by providing the `action` property, values are: 'push', 'replace', 'dispatch'.
Return value can be a Promise.
*/
beforeChange(to, from, action) {
},
/*
afterChange() will be called after the location changed.
Arguments:
to: Location object. The location changed to.
*/
afterChange(to, from, action) {
}
})
history.start()
HashHistory
import { HashHistory } from 'spa-history'
const history = new HashHistory({
beforeChange(to, from, action) {
},
afterChange(to, from, action) {
}
})
history.start()
HashHistory
has no base
option.
Location object
A location object is used for changing the current address.
It can be used in history.start(location)
, history.push(location)
, history.replace(location)
, history.dispatch(location)
, etc.
A string URL can be converted to a location object by history.normalize().
to
and from
parameter of beforeChange
and afterChange
hook are normalized location objects.
And a location object can be converted to a URL string by history.url().
{
path,
external,
query,
hash,
fullPath,
url,
state,
hidden,
appearPath
}
path
String
SPA Internal path, which has stripped the protocol, host, and base path.
external
Boolean
If path
is started with protocal, or external
is true
,
path
is treated as an external path, and will be converted to an internal path.
query
Object
| String
| Array
| URLSearchParams
| StringCaster<URLSearchParams>
query
accepts the same parameter types as URLSearchParams
constructor. Or it can be a StringCaster object that wraps a URLSearchParams
object.
hash
String
A string containing a #
followed by the fragment identifier of the URL.
If HashHistory
is used, the fragment identifier is followed by the second #
mark.
fullPath
String
. Read-only.
path + query string + hash
url
String
. Read-only.
An external relative URL which can be used as href
attribute of <a>
.
It is the same as history.url(location)
.
PathHistory
: base + path + query string + hashHashHistory
: # + path + query string + hash
state
Object
The state object is a JavaScript object which is associated with the history entry.
See state
parameter of history.pushState() for details.
hidden
Boolean
Indicate whether it is a hidden history entry. see history.push() for detail.
appearPath
String
If hidden
is true
and appearPath
is set, the location bar will show this address instead.
APIs
history.current
Location object
The current location. See location object.
history.start()
history.start(URL string | location)
Starts to handle the history.
In browser, if URL/location is not given, the default value is the current address.
history.normalize()
history.normalize(URL string | location)
Converts a URL string or an unnormalized location object to a normalized object.
If URL/location.path is started with protocal, or location.external
is true
, location.path
is treated as an external path, and will be converted to an internal path.
// PathHistory with base '/foo/bar/'
history.normalize('http://www.example.com/foo/bar/home?a=1#b')
/* ->
{
path: '/home',
query: new StringCaster(new URLSearchParams('a=1')),
hash: '#b',
fullPath: '/home?a=1#b',
url: '/foo/bar/home?a=1#b',
state: {}
}
*/
// same result as above
history.normalize({
path: '/foo/bar/home?a=1#b',
external: true
})
// same result as above
history.normalize('/home?a=1#b')
// same result as above
history.normalize({
path: '/home',
query: {
a: 1
},
hash: '#b'
})
// HashHistory
history.normalize('http://www.example.com/app/#/home?a=1#b')
/* ->
{
path: '/home',
query: new StringCaster(new URLSearchParams('a=1')),
hash: '#b',
fullPath: '/home?a=1#b',
url: '#/home?a=1#b',
state: {}
}
*/
history.url()
history.url(URL string | location)
Converts a internal URL string or a location object to an external URL which can be used as href
of <a>
.
history.url({
path: '/home',
query: {
a: 1
},
hash: '#b'
})
// or
history.url('/home?a=1#b')
/*
result:
HashHistory: #/home?a=1#b
PathHistory(with base: '/foo/bar/'): /foo/bar/home?a=1#b
*/
history.push()
history.push(URL string | location)
Pushs the location onto the history stack. beforeChange
will be called.
history.push('/home?a=1#b')
history.push({
path: '/home',
query: {
a: 1
},
hash: '#b'
})
// PathHistory, complete URL
history.push('http://www.example.com/foo/bar/home?a=1#b')
// HashHistory, complete URL
history.push('http://www.example.com/#/home?a=1#b')
You can push a location with state.
history.push({
path: '/home',
state: {
foo: 1,
bar: 2
}
})
And you can push a hidden location, which will not change the value of browser's address bar.
the hidden location is stored in window.history.state
.
history.push({
path: '/login',
state: {
foo: 1
},
// '/login' won't show in the location bar
hidden: true,
// optional. if set, the location bar will show this address instead
appearPath: '/buy'
})
history.replace()
history.replace(URL string | location)
Replaces the current history entry with the provided URL/location.
history.dispatch()
history.dispatch(URL string | location)
Sets the current location to the provided URL/location without changing the history session.
That is, the location of browser's address bar won't change. beforeChange
will be called.
history.setState()
history.setState(state)
Sets state of the current location. The state will be merged into history.current.state
history.go()
history.go(position, { silent = false, state = null } = {})
Counterpart of window.history.go()
. Returns a promise which will be resolved when popstate
event fired.
silent
: If true
, beforeChange
won't be called.
state
: If set, the state object will be merged into the state object of the destination location.
history.back()
history.back(options)
Same as history.go(-1, options)
.
history.forward()
history.forward(options)
Same as history.go(1, options)
.
history.captureLinkClickEvent()
history.captureLinkClickEvent(event)
Prevents the navigation when clicking the <a>
element in the container and the href
is an in-app address,
history.push()
will be called instead.
document.body.addEventListener('click', e => history.captureLinkClickEvent(e))
Dependencies
You can use @babel/polyfill and dom4 to meet the requirements.
Or use the polyfill.io service:
<script src="https://polyfill.io/v3/polyfill.min.js"></script>