首先: HTML5History也继承自History
var HTML5History = (function(History$$1){...})(History)
function getLocation (base) { //处理url
var path = decodeURI(window.location.pathname);
if (base && path.indexOf(base) === 0) {
path = path.slice(base.length);
}
return (path || '/') + window.location.search + window.location.hash
}
HTML5History构造方法,window监听popstate来触发组件切换和历史记录更新
function HTML5History (router, base) {
var this$1 = this;
History$$1.call(this, router, base); //执行History构造方法,继承实例方法
//滚动处理
var expectScroll = router.options.scrollBehavior;
var supportsScroll = supportsPushState && expectScroll;
if (supportsScroll) {
setupScroll();
}
//获取初始url
var initLocation = getLocation(this.base);
//给window添加popstate事件监听
window.addEventListener('popstate', function (e) {
var current = this$1.current;
// Avoiding first `popstate` event dispatched in some browsers but first
// history route not updated since async guard at the same time.
var location = getLocation(this$1.base);
if (this$1.current === START && location === initLocation) {
return
}
//调用transitionTo方法,完成跳转
this$1.transitionTo(location, function (route) {
if (supportsScroll) {
handleScroll(router, route, current, true);
}
});
});
}
原型方法:
1. HTML5History.prototype.go 调用window.history.go()方法
2. HTML5History.prototype.push 调用实例方法transitionTo,回调中执行pushState
var ref = this;
var fromRoute = ref.current;
this.transitionTo(location, function (route) {
pushState(cleanPath(this$1.base + route.fullPath));
handleScroll(this$1.router, route, fromRoute, false);
onComplete && onComplete(route);
}, onAbort);
3. HTML5History.prototype.replace 同上。调用实例方法transitionTo,回调中执行replaceState
4.HTML5History.prototype.ensureURL
//如果要跳转的地址跟当前地址不同
if (getLocation(this.base) !== this.current.fullPath) {
var current = cleanPath(this.base + this.current.fullPath);
//根据传入的push参数来决定是push还是replace新地址
push ? pushState(current) : replaceState(current);
}
pushState, replaceState
function pushState (url, replace) {
saveScrollPosition();
// try...catch the pushState call to get around Safari
// DOM Exception 18 where it limits to 100 pushState calls
var history = window.history;
try {
if (replace) {
history.replaceState({ key: _key }, '', url);
} else {
_key = genKey();
history.pushState({ key: _key }, '', url);
}
} catch (e) {
window.location[replace ? 'replace' : 'assign'](url);
}
}
function replaceState (url) {
pushState(url, true);
}