zoukankan      html  css  js  c++  java
  • 利用history实现无刷新跳转界面

      看标题是不是感觉很拽的样子,其实没什么啦,也就是时下常说的单页面应用。这种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代码:

    @-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 350ms ease-in-out;}
    .slideleftin{-webkit-animation:slideleftin 350ms ease-in-out;}
    .sliderightout{-webkit-animation:sliderightout 350ms ease-in-out;}
    .sliderightin{-webkit-animation:sliderightin 350ms ease-in-out;}
    .animatestart{position:absolute;top:0;left:0;z-index:3;100%;height:100%;overflow-x:hidden}
    .animatestart.page-container{overflow-x:hidden;-webkit-transform:translate3d(0,0,0);-webkit-backface-visibility:hidden;background-color:#f5f5f5}
    

      然后是控制界面各个元素的显示位置的css代码,排列组合各个界面(div p button span)。

    *{
    	padding: 0;
    	margin: 0;
    }
    .none {
    	display: none;
    }
    div {
      position: absolute;
      height: 100%;
       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;
       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按钮:

    //首先给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事件,也就是回退/前进行为的事件:

    //利用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值)却并不会这样做。当然,你可以使用你的聪明才智改变这种情况,那就见仁见智了。

  • 相关阅读:
    python全栈开发,Day43(引子,协程介绍,Greenlet模块,Gevent模块,Gevent之同步与异步)
    python全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)
    python全栈开发,Day41(线程概念,线程的特点,进程和线程的关系,线程和python理论知识,线程的创建)
    处理大并发之五 使用libevent利器bufferevent
    [转]./configure,make,make install的作用
    [转]Centos安装zeromq和jzmq
    [zhuan] linux 下 wxWidgets 安装,编译
    [转]面向过程的分析(POA),和面向对象的分析(OOA)
    【转】libevent和基于libevent的网络编程
    [转] Linux下 config/configure/Configure、make 、make test/make check、sudo make install 的作用
  • 原文地址:https://www.cnblogs.com/constantince/p/4560897.html
Copyright © 2011-2022 走看看