hash_html5_history.js /** * HashHistory * @link https://zhuanlan.zhihu.com/p/27588422 */// hash的改变会自动添加到浏览器的访问历史记录中。function pushHash (path) { window.location.hash = path}// replace()方法与push()方
/** * HashHistory * @link https://zhuanlan.zhihu.com/p/27588422 */ // hash的改变会自动添加到浏览器的访问历史记录中。 function pushHash (path) { window.location.hash = path } // replace()方法与push()方法不同之处在于,它并不是将新路由添加到浏览器访问历史的栈顶,而是替换掉当前的路由 function replaceHash (path) { const i = window.location.href.indexOf('#') window.location.replace( window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path ) } // 用户还可以直接在浏览器地址栏中输入改变路由. SO, 可以为hash的改变添加监听事件 // window.addEventListener("hashchange", funcRef, false) window.addEventListener('hashchange', () => { if (!ensureSlash()) { return } this.transitionTo(getHash(), route => { replaceHash(route.fullPath) }) }) function ensureSlash (): boolean { const path = getHash() if (path.charAt(0) === '/') { return true } replaceHash('/' + path) return false } export function getHash (): string { const href = window.location.href const index = href.indexOf('#') return index === -1 ? '' : href.slice(index + 1) } /** * HTML5History * HTML5开始,History interface提供了两个新的方法:pushState(), replaceState() 使得我们可以对浏览器历史记录栈进行修改 * @link https://zhuanlan.zhihu.com/p/27588422 */ // // stateObject: 当浏览器跳转到新的状态时,将触发popState事件,该事件将携带这个stateObject参数的副本 // title: 所添加记录的标题 // URL: 所添加记录的URL window.history.pushState(stateObject, title, URL) window.history.replaceState(stateObject, title, URL) // src/util/push-state.js export function pushState (url?: string, replace?: boolean) { saveScrollPosition() // try...catch the pushState call to get around Safari // DOM Exception 18 where it limits to 100 pushState calls const 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) } } export function replaceState (url?: string) { pushState(url, true) } // 在HTML5History中添加对修改浏览器地址栏URL的监听 window.addEventListener('popstate', e => { const current = this.current this.transitionTo(getLocation(this.base), route => { if (expectScroll) { handleScroll(router, route, current, true) } }) }) ensureURL (push?: boolean) { if (getLocation(this.base) !== this.current.fullPath) { const current = cleanPath(this.base + this.current.fullPath) push ? pushState(current) : replaceState(current) } } export function getLocation (base: string): string { let path = window.location.pathname if (base && path.indexOf(base) === 0) { path = path.slice(base.length) } return (path || '/') + window.location.search + window.location.hash }