SPA单页面应用实现前进与后退功能,完整解决方案

前言

  在应用ajax与服务器进行数据交互的过程中,实现了页面的局部刷新,极大地改善了用户体验。但是却出现了一些问题:用户发出若干次ajax请求后,浏览器的前进后退功能失效了,这时点击浏览器返回按钮,会直接返回到最初的url资源页面
  比如,在一个页面中的分页模块,使用ajax与后台进行数据交互,如若不做特殊处理,用户浏览了若干页后,假设现在正在浏览第六页,用户现在点击返回键,不会返回到第五页的数据界面,而是是直接返回上一个url资源界面。出现这种情况的原因是,浏览器会记录地址栏的url资源链接,如果url链接发生变化,浏览器会把该url链接保存到一个特殊的数据结构中,这样当用户点击返回与前进按钮时,会快速访问已经被记录的url链接资源
  而使用ajax进行局部数据更新时,浏览器地址栏的url链接没有改变,所以浏览器也就不会保存记录。这时候的结果就是,点击返回按钮出现了非期待性结果。这种问题在SPA(single page web application)单页面应用中尤为常见。

解决方案

  通过设置window.location.hash
  location.hash用于设置页面的标签值。
假设一个名为hash.html的页面主题内容如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<style>
	div{
	height:600px;
	width:500px;
	}
</style>
<body>
	<a href="#section3">to part3</a>
	<div id="section1">part1</div>
	<div id="section2">part2</div>
	<div id="section3">part3</div>
</body>
</html>

浏览器访问该页面:
hash.html
点击超链接to part3,定位到part3部分:
#section3
我们看到浏览器的地址栏改变了,后面多了个#section3,这个部分就是location.hash的值。
虽然我们一直在hash.html这个页面,但是增加location.hash值后,浏览器的url地址栏资源链接改变了,浏览器就会把该url链接作为历史记录保存下来。这时候点击返回按钮,我们能回到hash.html的原始位置:hash.html。即:浏览器认为hash.html与hash.html#section3是两个不同的url,所以浏览器会保存上述url链接。
  由此,我们可以在需要的时候,在ajax与服务器进行交互时,设置
window.location.hash的值:

function updateView (attr){
            $.ajax({
            	type:...,
                url:...,
                data:{attr : attr},
                success:function(datas){
                	//设置hash值
                	 window.location.hash = "#"+attr;
                	//do somthing
                },
                error:function(status){
					//do somthing
                }
            });
        }

这个值最好是该次请求所需的参数。假设该请求代表A.html页面中的翻页功能,即:调用updateView (1),代表查看第一页,调用过后,浏览器地址栏变为:A.html#1,再次调用updateView (6),查看第六页,浏览器地址栏变为:A.html#6
这时,设置onhashchange事件监听:

 window.onhashchange=function(){
 	var attr=window.location.hash.replace("#","");
 	updateView (attr);
    	 }

用户依次访问了第一页,第六页,这时点击浏览器返回键,onhashchange事件触发,获取到attr的值为1;调用updateView (1),显示第一页的视图,用户体验良好,但服务器压力增大。

BUG解决

  这样处理后,用户点击第一页的视图,ajax请求成功后,会主动改变hash值,这时候又触发onhashchange,又一次更新视图,两次访问服务器。
设置一个全局变量,记录hash值的改变是怎样引起的:

 var innerDocClick;
        $('body').on('mouseleave',function(){
        	innerDocClick=false;//鼠标在页面外(点击了返回按钮)
        });
        $('body').on('mouseover',function(){
        	innerDocClick=true;//鼠标在页面内(没有点击返回按钮)
        });
        
        window.onhashchange=function(){
        	if(!innerDocClick)//若点击了返回按钮
        		{
        			var attr=window.location.hash.replace("#","");
 					updateView (attr);
        		}
    	 }

同理,刷新功能不攻自破。
暂时解决问题。
附:完整SPA展示:www.lword.top

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值