看标题是不是感觉很拽的样子,其实没什么啦,也就是时下常说的单页面应用。这种web形式在如今的移动端十分流行,毕竟在移动端频繁得去刷新界面不是很友好,而且还费流量。今天我们要做一个小的app(移动端),来揭秘history的秘密。首先我们了解一下核心方法:
window.history.pushState:方法:为histroy建立历史记录,该方法传入三个函数:1、对应url的信息2、下一个界面的title 3 、需要你动态改变的地址栏中德url.
window.history.state:属性:当前的history中的信息状态。
window.history.replaceState:方法:以本次信息替换之前的history内容记录,传入的参数与第一个相同。
首先,你不必执着于上面的一些定义。在我第一次看到这些说明的时候我也是一头雾水,真正了解他们是在使用它们之后。事不宜迟,我们首先创造出html结构来:
要实现简单的界面切换,我们首先要创建出三个界面,当然为了方便,这三个界面就是是三个div(a,b,c 整屏大,绝对定位)和一个按钮(用来添加历史内容记录):
<!DOCTYPE html> <html> <head> <title>history back</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <script type="text/javascript" src="zepto.js"></script> <link rel="stylesheet" type="text/css" href="history.css"> </head> <body> <div class="a"><p>What we talk about when we talk about love</p><span>A</span></div> <div class="b none"><p>Quell nous sommes parlons lorsqur nous parlons d'amour</p><span>B</span></div> <div class="c none"><p>当我们在談論爱情的时候,我们在談論些什么</p><span>C</span></div> <button class="forward">FORWARD</button> </body> </html>
翻页效果,可以简单一些,在这里,我做了动画,利用css3的3d动画属性,打造简单的动画效果。如果你觉得麻烦,可以直接元素的显示和隐藏,但在实际的项目中,我推荐利用动画过度效果,这样不仅提高客户体验,而且你可以利用到css3的许多新特新,对于web2.0时代的前端精英来说这是必修课。下面是切换效果的css代码:
1 2 3 4 5 6 7 8 9 10 11 | @-webkit-keyframes sliderightout{from{-webkit-transform:translateX( 0px );}to{-webkit-transform:translateX( 50% );}} @-webkit-keyframes slideleftin{from{-webkit-transform:translateX( -50% );}to{-webkit-transform:translateX( 0px );}} @-webkit-keyframes slideleftout{from{-webkit-transform:translateX( 0px );}to{-webkit-transform:translateX( -50% );}} @-webkit-keyframes sliderightin{from{-webkit-transform:translateX( 50% );}to{-webkit-transform:translateX( 0px );}} .slideleftout{-webkit-animation:slideleftout 350 ms ease-in-out;} .slideleftin{-webkit-animation:slideleftin 350 ms ease-in-out;} .sliderightout{-webkit-animation:sliderightout 350 ms ease-in-out;} .sliderightin{-webkit-animation:sliderightin 350 ms ease-in-out;} .animatestart{ position : absolute ; top : 0 ; left : 0 ; z-index : 3 ; width : 100% ; height : 100% ;overflow-x: hidden } .animatestart.page-container{overflow-x: hidden ;-webkit-transform:translate 3 d( 0 , 0 , 0 );-webkit-backface- visibility : hidden ; background-color : #f5f5f5 } |
然后是控制界面各个元素的显示位置的css代码,排列组合各个界面(div p button span)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | *{ padding : 0 ; margin : 0 ; } . none { display : none ; } div { position : absolute ; height : 100% ; width : 100% ; color : #fff ; } div span { display : block ; font-size : 6.5em ; text-align : center ; } div p { font-size : 1.2em ; } button { position : absolute ; height : 40px ; width : 100px ; border-radius: 6px ; background : #fff ; bottom : 50px ; border : 0 ; } button.back { left : 20px ; } button.forward { right : 20px ; } .a { background : #19a39e ; } .b{ background : rgb ( 245 , 81 , 81 ); } .c{ background : rgb ( 71 , 142 , 30 ); } |
接下来是重点,我们的思路是首先给浏览器的历史填充记录,这个需要手动完成,这也就是button的使命,因此,我们首先绑定forward按钮:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | //首先给history添加一条记录,使得第一个界面和后来的界面看起来是永远的以page=x结尾 window.history.pushState({info: 'a' }, 'Page' , '?page=a' ); //数据源 var source = [ {cls: 'a' , url: '?page=a' }, {cls: 'b' , url: '?page=b' }, {cls: 'c' , url: '?page=c' } ], //数据源的下表, k = 0, //界面涨势的属性列表 index = [ 'a' , 'b' , 'c' ], //记录每个界面跳转的顺序的列表 stoage = []; //绑定按钮的tap事件,我们在移动端做测试,用的是tap,zepto会帮我们转译该事件 $( '.forward' ).on( 'tap' , function (){ if (source[k]) { //取下一个界面的数据源 var m = source[++k]; //在这里填充history记录,pushstate是方法是不会引起界面刷新的,但是却会改变浏览器的回退/前进行为,执行这一步的时候可以看到地址栏中的url变化了。 window.history.pushState({info:m.cls}, 'Page' , m.url); //储存该节目名称到stoage列表中 stoage.push(window.history.state.info); //下面是切换的动画,因为这里力求简单做的是一直向前走的动作,所以动画是从右到左的切换顺序 $( '.' + m.cls).removeClass( 'none' ).addClass( "animatestart sliderightin" ); setTimeout( function (){ //动画结束时重置class $( '.' + source[k -1].cls).addClass( 'none' ); $( '.' + m.cls).removeClass( 'animatestart sliderightin' ); }, 350); } }) |
上面做的事情,还仅仅是在界面中利用dom事件跳转界面,要利用前进和后退按钮实现无刷新跳转节目我们需要侦听popstate事件,也就是回退/前进行为的事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | //利用stoage的存储和index列表中的先后规则,放回动画翻转顺,是从左到右,还是从右到左 function j() { var l = stoage.length; if (index.indexOf(stoage[l-2]) < index.indexOf(stoage[l-1])) { return 'animatestart sliderightin' ; } else { return 'animatestart slideleftin' ; } } //开始监听浏览器的前进/后退行为 $(window).on( 'popstate' , function (state) { //移除按钮 $( '.forward' ).remove(); //将本界面名称存入stoage列表中 stoage.push(window.history.state.info); //取得上一个界面的名称 var thiscls = stoage[stoage.length - 2]; //取得当前界面的名称 var nextcls = stoage[stoage.length - 1]; //对比两个界面获得动画效果 var cls = j(); //执行动画效果 $( '.' + nextcls).removeClass( 'none' ).addClass(cls); setTimeout( function (){ //动画结束时重置clas $( '.' + thiscls).addClass( 'none' ); $( '.' + nextcls).removeClass(cls); }, 350); }); |
通过点击按钮,这时候看到,浏览器的回退按钮已经可以启用,我们点击回退,观察url的变化和界面的切换变化
page=c变成了page=b,动画效果是从左到右,界面就这样切换成功,界面并无刷新,多试几次。
A->B
B->C
这样我们就实现了点击回退/前进按钮实现单界面无刷新切换了。
事情还有另一种做法,即使利用hash变化监听onhashchange来实现无刷新的界面切换,你一定想到了backbone就是这样做的。不过对于小一点的项目,我建议用'?'(传值)不是'#'号(hash),因为无刷下跳转意味着和利器ajax一起使用,使用‘?’号的好处是,即使用户强制刷新了界面,我们也可以给后台传参数,告诉后台我们正处于哪一个界面,需要什么样的数据,从而和前段的ajax统一起来。因为?号代表search,刷新的时候给后台会传入get类型的数据的。而#号(hash值)却并不会这样做。当然,你可以使用你的聪明才智改变这种情况,那就见仁见智了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?