history和hash跳转

一、为何会有history和hash

为了实现单页应用(SPA),让用户体验更好,所以使用前端路由进行跳转,而前端路由跳转的两种方式,就是hash和history。

改变路由在主机名和端口号不变的情况下,可以改变的只有路径部分(location.pathname)和hash值,改变hash值不会触发页面刷新,也不会请求后台,所以可以将其作为前端路由跳转的一种方式;常规改变location.pathname会请求后台并刷新页面,比如控制台执行:location.pathname="/a",但是HTML5 新增方法history.pushState会改变location.pathname但不会请求后台,所以可将其作为前端路由跳转的第二种方式。

二、用hash和history来实现路由

1、hash实现原理:用 hashchange 来监听hash值的变化,然后根据hash值来进行渲染,下面看一个简单实例

<body>
	<a href="#/home">home</a>
	<a href="#/about">about</a>
	<div id="app"></div>
	<script type="text/javascript">
		//这里也可以用 location.hash="/home"来改变hash值
		let app=document.getElementById("app")
		window.addEventListener("hashchange",function(event){
			let hash=location.hash.slice(1) || '/';
			if(hash=="/home"){
				app.innerHTML="我是home页面"
			}else if(hash=="/about"){
				app.innerHTML="我是about页面"
			}
		})
	</script>
</body>

2、history实现原理:通过history.popState()来压入页面,造成路由变化,同时触发自写函数来实现页面变化

<body>
	<p onclick="pathchange('/home')">home</p>
	<p onclick="pathchange('/about')">about</p>
	<div id="app"></div>
	<script type="text/javascript">
		let app=document.getElementById("app");
		let orginpath=location.pathname;//记录原始pathname
		function pathchange(path){
			let allpath=orginpath+path;//生成新的pathname
			history.pushState(null,null,allpath);//改变pathname
			if(path=="/home"){
				app.innerHTML="我是home页面"
			}else if(path=="/about"){
				app.innerHTML="我是about页面"
			}
		}
		//history.pushState和history.replaceState不会触发popstate
		window.addEventListener('popstate', (e) => {
			console.log(123)
		});
	</script>
</body>

 

三、history和hash的优缺点

1、hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)
它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。    

2、history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。
优点:

  • pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 # 后面的部分,因此只能设置与当前 URL 同文档的 URL;
  • pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;而 hash 设置的新值必须与原来不一样才会触发动作将记录添加到栈中;
  • pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串;
  • pushState() 可额外设置 title 属性供后续使用。

缺点:

  • history模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.abc.com/book/id。如果后端缺少对 /book/id 的路由处理,将返回 404 错误。

四、history对象API

  1. window.history.length——返回当前会话浏览过的页面数量
  2. window.history.go( )——当前页面在会话浏览历史记录中进行移动,当参数为 0 , undefined , null , false 相当于执行window.location.reload()
  3. window.history.back()——后退一个页面
  4. window.history.forward()——无参数,前进一个页面一个页面

————HTML5 新增————

  1. window.history.state——该参数是只读的,与当前页面记录关联的储存对象,pushState和replaceState传的参数,前进后退一直查询的到
  2. window.history.pushState(data, title, ?url)——在会话浏览历史记录中添加一条记录。
  3. window.history.replaceState(data, title, ?url)——修改会话浏览历史的当前记录     
  • 相关参数:
  • data:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
  • title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
  • url:新的网址,必须与当前页面处在同一个域(不然会报错)。浏览器的地址栏将显示这个网址。

window.history.pushState({a:"132"}, "null", "/e”) 和window.history.pushState({a:"132"}, null, "https://www.baidu.com/e")效果一样

五、location 属性

  1. location.href——完整的url    
  2. location.protocol——当前URL的协议,包括 :; 比如 https:     
  3. location.host——主机名和端口号,如果端口号是80(http)或443(https), 那就会省略端口号,比兔 www.baidu.com:8080
  4. location.hostname——主机名:比如:www.baidu.com
  5. location.port——端口号;比如8080
  6. location.pathname——url的路径部分,从 / 开始; 比如 https://www.baidu.com/s?ie=utf-8,那么 pathname = '/s'了
  7. location.search——查询参数,从?开始;比如 https://www.baidu.com/s?ie=utf-8 那么 search = '?ie=utf-8'
  8. location.hash——hash是页面中的一个片段,从 # 开始的,比如 https://www.baidu.com/#/a/b 那么返回值就是:"#/a/b"

 

 

 

 

 

 

 


 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值