当前位置:网站首页>Principles and differences between hash and history
Principles and differences between hash and history
2022-06-24 00:05:00 【Front end small tips】
Current single page application (SPA) More and more become the front-end mainstream , A major feature of single page applications is the use of front-end routing , The front end directly controls the route jump logic , It is no longer controlled by the back-end personnel , This gives the front end more freedom .
At present, there are two main ways to implement front-end routing :hash Patterns and history Pattern , Here are the details .
1. hash Pattern
For example, when making anchor jump with hyperlinks , You will find ,url Followed by "#id",hash The value is url In the from "#" The part from the beginning to the end of No .
hash When the value changes, the browser will not reissue the request , But it triggers window.hashChange event , If we were hashChange Get the current... From the event hash value , And according to hash Value to modify the page content , The purpose of front-end routing is achieved .
<!-- html: The menu href Set to hash form ,id by app Place page content in -->
<ul id="menu">
<li>
<a href="#index"> home page </a>
</li>
<li>
<a href="#news"> information </a>
</li>
<li>
<a href="#user"> Personal center </a>
</li>
</ul>
<div id="app"></div>// stay window.onhashchange In order to get hash value , According to different values , modify app Different contents in , It has the effect of routing
function hashChange(e){
// console.log(location.hash)
// console.log(location.href)
// console.log(e.newURL)
// console.log(e.oldURL)
let app = document.getElementById('app')
switch (location.hash) {
case '#index':
app.innerHTML = '<h1> This is the home page </h1>'
break
case '#news':
app.innerHTML = '<h1> This is the news </h1>'
break
case '#user':
app.innerHTML = '<h1> This is a personal focus </h1>'
break
default:
app.innerHTML = '<h1>404</h1>'
}
}
window.onhashchange = hashChange
hashChange()The above implementation method is relatively simple , We can package it again :
class Router {
constructor(){
this.routers = [] // Store our routing configuration
}
add(route,callback){
this.routers.push({
path:route,
render:callback
})
}
listen(callback){
window.onhashchange = this.hashChange(callback)
this.hashChange(callback)() // There is no trigger when you first enter the page hashchange, You have to call it alone
}
hashChange(callback){
let self = this
return function () {
let hash = location.hash
console.log(hash)
for(let i=0;i<self.routers.length;i++){
let route = self.routers[i]
if(hash===route.path){
callback(route.render())
return
}
}
}
}
}
let router = new Router()
router.add('#index',()=>{
return '<h1> This is the home page </h1>'
})
router.add('#news',()=>{
return '<h1> This is the news </h1>'
})
router.add('#user',()=>{
return '<h1> This is a personal focus </h1>'
})
router.listen((renderHtml)=>{
let app = document.getElementById('app')
app.innerHTML = renderHtml
})Achieve one Router class , adopt add Method to add a routing configuration , The first parameter is the routing path , The second parameter is render function , Return to the page you want to insert html; adopt listen Method , monitor hash change , And return each route html, Insert into app in . So we have a simple hash route .
2. history Pattern
hash The pattern looks ugly , Bring both "#" Number , We can also take history Pattern ,history It is the normal connection form we usually see .history The pattern is based on window.history Object method .
stay HTML4 in , Has supported window.history Object to control page history jump , Common methods include :
history.forward(): Take a step forward in historyhistory.back(): Step back in historyhistory.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 , Newly added API Include :
history.pushState(data[,title][,url]): Append a record to the historyhistory.replaceState(data[,title][,url]): Replace the current page's information in history .history.state: Is an attribute , You can get the current page state Information .window.onpopstate: It's an event , Click the browser Back button or js callforward()、back()、go()Trigger when . A listening function can be passed in event object ,event.stateThat is, throughpushState()orreplaceState()Method passed in data Parameters
history The pattern principle can be understood in this way , First we need to transform our hyperlinks , Add... To each hyperlink onclick Method , Prevent default hyperlinks from jumping , change to the use of sth. history.pushState or history.replaceState To change... In the browser url, And modify the page content . Because through history Of api adjustment , It does not send a request to the back end , Therefore, the purpose of front-end routing is achieved .
If the user uses the browser's forward and backward buttons , It triggers window.onpopstate event , The listening page modifies the page content according to the routing address .
You don't have to use hyperlinks , Any element can be used as a menu , Just pass in the click event history Adjust it .
<!--html:-->
<ul id="menu">
<li>
<a href="/index"> home page </a>
</li>
<li>
<a href="/news"> information </a>
</li>
<li>
<a href="/user"> Personal center </a>
</li>
</ul>
<div id="app"></div>//js:
// Transform hyperlinks , Prevent default jump , The default jump will refresh the page
document.querySelector('#menu').addEventListener('click',function (e) {
if(e.target.nodeName ==='A'){
e.preventDefault()
let path = e.target.getAttribute('href') // Get the hyperlink href, Change it to pushState Jump , Do not refresh page
window.history.pushState({},'',path) // Modify the url Address
render(path) // according to path, Change page content
}
})
function render(path) {
let app = document.getElementById('app')
switch (path) {
case '/index':
app.innerHTML = '<h1> This is the home page </h1>'
break
case '/news':
app.innerHTML = '<h1> This is the news </h1>'
break
case '/user':
app.innerHTML = '<h1> This is a personal focus </h1>'
break
default:
app.innerHTML = '<h1>404</h1>'
}
}
// Monitor browser forward and backward Events , And render the page according to the current path
window.onpopstate = function (e) {
render(location.pathname)
}
// Enter the page for the first time to display the home page
render('/index')The above writing is too low, We can use classes to encapsulate , adopt add Method to add a route , adopt pushState To jump , Change the jump mode of all hyperlinks during initialization :
class Router {
constructor(){
this.routers = []
this.renderCallback = null
}
add(route,callback){
this.routers.push({
path:route,
render:callback
})
}
pushState(path,data={}){
window.history.pushState(data,'',path)
this.renderHtml(path)
}
listen(callback){
this.renderCallback = callback
this.changeA()
window.onpopstate = ()=>this.renderHtml(this.getCurrentPath())
this.renderHtml(this.getCurrentPath())
}
changeA(){
document.addEventListener('click', (e)=> {
if(e.target.nodeName==='A'){
e.preventDefault()
let path = e.target.getAttribute('href')
this.pushState(path)
}
})
}
getCurrentPath(){
return location.pathname
}
renderHtml(path){
for(let i=0;i<this.routers.length;i++){
let route = this.routers[i]
if(path===route.path){
this.renderCallback(route.render())
return
}
}
}
}
let router = new Router()
router.add('/index',()=>{
return '<h1> This is the home page </h1>'
})
router.add('/news',()=>{
return '<h1> This is the news </h1>'
})
router.add('/user',()=>{
return '<h1> This is a personal focus </h1>'
})
router.listen((renderHtml)=>{
let app = document.getElementById('app')
app.innerHTML = renderHtml
})Of course , The above implementation is only a very rudimentary demo, It cannot be used in real development scenarios , Just to deepen the understanding of front-end routing .
3. hash Patterns and history The difference between patterns
- hash The pattern is ugly ,history The model is more elegant
- pushState Set up new URL It can be related to the current URL Any of the same origin URL; and hash You can only modify # Back section , Therefore, you can only set the URL
- pushState Set up new URL Can be compared with the current URL As like as two peas , This also adds records to the stack ; and hash The new value set must be different from the original value to trigger the record to be added to the stack
- pushState adopt stateObject You can add any type of data to the record ; and hash Only short strings can be added
- pushState Additional settings are available title Property for subsequent use
- hash compatible IE8 above ,history compatible IE10 above
- history The pattern requires back-end cooperation to point all accesses to index.html, Otherwise, the user refreshes the page , It can lead to 404 error
边栏推荐
- DO280OpenShift访问控制--管理项目和账户
- Total number of combinations ii[each element can only be solved by + once]
- Smart doc + Torna compatible version
- Restore IP address [standard backtracking + standard pruning]
- What is the use of AI technology in the medical field?
- High imitation Betta app
- [technical grass planting] the tail of the "double 11" event. Let's talk about how much discount the message push service package is!
- Android App Bundle探索,客户端开发面试题目
- AI技术在医学领域有什么用?
- . Net
猜你喜欢

物联网卡设备接入EasyCVR,如何查看拉流IP以及拉流时间?

Six complete open source projects, learning enough at a time

Detailed explanation of index invalidation caused by MySQL

Docker redis cluster configuration

如何入门机器学习?
![Restore IP address [standard backtracking + standard pruning]](/img/e6/5f9d2a5af973b6c7051ed434a4b93d.png)
Restore IP address [standard backtracking + standard pruning]

Solve the problem of project dependency red reporting

List<? Extensions T > and list <? Super T > difference

Quantitative investment model -- research interpretation of high frequency trading market making model (Avellaneda & Stoikov's) & code resources

解决项目依赖报红问题
随机推荐
【图像检测显著图】基于matlab失真提示鱼眼图显著图计算【含Matlab源码 1903期】
Nlp-d58-nlp competition d27 & question brushing D14 & Paper Reading & MathType
[technical grass planting] use the shared image function to realize the offline switching from CVM to LH
如何利用數倉創建時序錶
Confused test / development programmers, different people have different stories and different puzzles
MySQL architecture (basic)
DO280OpenShift访问控制--管理项目和账户
I was cheated by my colleagues to work overtime on weekends. I haven't seen redis used like this...
微信小程序中three.js的canvas非全屏情况下射线检测不准确问题解决方案
Keywords such as extern and struct
抖音实战~密码找回
docker redis集群配置
Android 3年外包工面试笔记,有机会还是要去大厂学习提升,作为一个Android程序员
Facebook open source shimmer effect
Total number of combinations ii[each element can only be solved by + once]
【面试经验包】面试被吊打经验总结(一)
Under the background of aging, the comprehensive energy efficiency management platform escorts hospitals
extern、struct等关键字
Three types of transactions in EF core (saveChanges, dbcontexttransaction, transactionscope)
[things about gbase] gbase 8s high availability technology and case analysis (issue 02)