前生今世,与浏览器历史堆栈管理

History API 与浏览器历史堆栈管理

2016/07/25 · HTML5 ·
History,
HTML5,
浏览器

正文小编: 伯乐在线 –
欲休
。未经小编许可,禁止转发!
迎接参加伯乐在线 专辑撰稿人。

移步端支付在少数场景中负有异乎经常必要,如为了进步用户体验和加速响应速度,平常在一部分工程使用SPA架构。传统的单页应用基于url的hash值实行路由,那种达成不设有包容性难题,可是缺点也有–针对不辅助onhashchange属性的IE6-7必要设置定时器不断检查hash值改变,品质上并不是很谈得来。

而现行,在运动端支出中HTML5规范给我们提供了一个History接口,使用该接口可以随心所欲支配历史记录。本文并不详细介绍History接口,而是研究History接口怎么样影响浏览器历史堆栈,并且应用那个规律选择到具体的实际工作中,提议二种历史记录保存策略,使路由逻辑更清楚,让SPA更便于。

HTML 5 History API的”前生今世”

2014/10/23 · HTML5 ·
HTML5

初稿出处:
tuts+   译文出处:遗忘浅思的博客(@dwido)   

History是有趣的,不是啊?在头里的HTML版本中,大家对浏览历史记录的操作尤其简单。大家可以来回使用可以应用的法子,但那就是成套大家能做的了。

不过,利用HTML 5的History
API,大家得以更好的支配浏览器的历史记录了。例如:我们得以添加一条记下到历史记录的列表中,或者在尚未刷新时,可以创新地址栏的URL。

HTML 5 History API的”前生今世”,api前生今世

原文:An Introduction To The HTML5 History API

译文:关于HTML 5 History API 的介绍

译者:dwqs

History是幽默的,不是啊?在事先的HTML版本中,我们对浏览历史记录的操作越发有限。大家可以来回使用可以行使的格局,但那就是漫天大家能做的了。

不过,利用HTML 5的History
API,大家得以更好的操纵浏览器的历史记录了。例如:我们可以添加一条记下到历史记录的列表中,或者在未曾刷新时,可以立异地址栏的URL。

 

怎么介绍History API ?

        在 那篇小说中,我们将精晓HTML 5中History
API的源点。在此从前,大家平日选拔散列值来改变页面内容,尤其是那么些对页面尤其主要的情节。因为尚未刷新,所以对于单页面应用,改变其URL是不容许
的。别的,当您转移URL的散列值值,它对浏览器的历史记录没有此外影响。

        然后,现在对于HTML 5的History
API来说,这几个都是足以随意已毕的,可是由于单页面应用没须求运用散列值,它可能须要格外的支出脚本。它也允许大家用一种对SEO友好的方法确立新利用。其它,它能压缩带宽,可是该怎么讲明呢?

        在小说中,我将用History API开发一个单页应用来证实上述的标题。

       
那也代表自己必须先在首页加载要求的资源。现在始发,页面仅仅加载要求的情节。换句话说,应用并不是一发轫就加载了任何的始末,在伏乞第一个使用内容时,才会被加载。

注意,您要求执行一些劳务器端编码只提供一些资源,而不是全部的页面内容。

 

浏览器援救

         在写那篇小说的时候,各主流浏览器对History
API的支撑是丰裕正确的,可以点击那里查看其协理意况,这一个链接会告诉您辅助的浏览器,并行使在此以前,总有出彩的实践来检测协助的一定作用。

        
为了用变成格局确定浏览器是不是接济这几个API,可以用上面的一条龙代码检验:

return !!(window.history && history.pushState);

 

         其余,我指出参考一下那篇小说:Detect Support for Various HTML5
Features.(ps:后续会翻译)

         如若你是用的当代浏览器,可以用上面的代码:

if (Modernizr.history) {
    // History API Supported
}

 

         即使你的浏览器不援救History API,可以选择history.js代替。

 

使用History

        HTML 5提供了三个新办法:

              1、history.pushState();               
2、history.replaceState();

       
三种办法都同意大家添加和立异历史记录,它们的工作规律相同并且可以加上数量一样的参数。除了艺术之外,还有popstate事件。在后文司令员介绍怎么使用和如曾几何时候利用popstate事件。

        pushState()和replaceState()参数一样,参数表达如下:

              1、state:存储JSON字符串,可以用在popstate事件中。

             
2、title:现在多数浏览器不帮忙依旧忽视这么些参数,最好用null代替

             
3、url:任意有效的URL,用于创新浏览器的地址栏,并不在乎URL是或不是业已存在地址列表中。更要紧的是,它不会重复加载页面。

       
五个章程的显要不同就是:pushState()是在history栈中添加一个新的条规,replaceState()是替换当前的记录值。要是你还对那一个有迷惑,就用一些演示来表达那个不一样。

       
假使大家有三个栈块,一个标志为1,另一个标志为2,你有第两个栈块,标记为3。当执行pushState()时,栈块3将被添加到已经存在的栈中,由此,栈就有3个块栈了。

       
同样的假诺情景下,当执行replaceState()时,将在块2的库房和停放块3。所以history的记录条数不变,也就是说,pushState()会让history的数据加1.

相比较结实如下图:

       
到此,为了操纵浏览器的历史记录,我们忽视了pushState()和replaceState()的事件。不过如若浏览器总括了众多的不成记录,用户可能会被重定向到这个页面,或许也不会。在那种情况下,当用户使用浏览器的腾飞和向下导航按钮时就会时有发生意想不到的难点。

       
即使当大家选用pushState()和replaceState()进行拍卖时,期待popstate事件被触发。但其实,情形并不是这么。相反,当您浏览会话历史记录时,不管你是点击前进或者后退按钮,仍然采纳history.go和history.back方法,popstate都会被触发。

前生今世,与浏览器历史堆栈管理。In WebKit browsers, a popstate event would be triggered after
document’s onload event, but Firefox and IE do not have this
behavior.(在WebKit浏览器中,popstate事件在document的onload事件后触发,Firefox和IE没有那种行为)。

      

Demo示例

       HTML:

<div class="container">
    <div class="row">
        <ul class="nav navbar-nav">
            <li><a href="home.html" class="historyAPI">Home</a></li>
            <li><a href="about.html" class="historyAPI">About</a></li>
            <li><a href="contact.html" class="historyAPI">Contact</a></li>
        </ul>
    </div>
    <div class="row">
        <div class="col-md-6">
            <div class="well">
                Click on Links above to see history API usage using <code>pushState</code> method.
            </div>
        </div>
        <div class="row">   
            <div class="jumbotron" id="contentHolder">
                <h1>Home!</h1>
                <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            </div>
        </div>
    </div>
</div>

 

       JavaScript:

<script type="text/javascript">
    jQuery('document').ready(function(){

        jQuery('.historyAPI').on('click', function(e){
            e.preventDefault();
            var href = $(this).attr('href');

            // Getting Content
            getContent(href, true);

            jQuery('.historyAPI').removeClass('active');
            $(this).addClass('active');
        });

    });

    // Adding popstate event listener to handle browser back button 
    window.addEventListener("popstate", function(e) {

        // Get State value using e.state
        getContent(location.pathname, false);
    });

    function getContent(url, addEntry) {
        $.get(url)
        .done(function( data ) {

            // Updating Content on Page
            $('#contentHolder').html(data);

            if(addEntry == true) {
                // Add History Entry using pushState
                history.pushState(null, null, url);
            }

        });
    }
</script>

 

          Demo 1:HTML 5 History API – pushState

历史条目在浏览器中被统计,并且可以很不难的使用浏览器的进化和滞后按钮。View
Demo 
(ps:你在点击demo1的选项卡时,其记录会被添加到浏览器的历史记录,当点击后退/前进按钮时,能够重回/跳到你前边点击的选项卡对应的页面)

          Demo 2:HTML 5 History API – replaceState

野史条目在浏览器中被更新,并且不可能动用浏览器的提升和向下按钮举行浏览。View
Demo 
(ps:你在点击demo1的选项卡时,其记录会被沟通当前浏览器的历史记录,当点击后退/前进按钮时,不可以回去/跳到您前边点击的选项卡对应的页面,而是再次回到/跳到你进去demo2的上一个页面)

小结(ps:喜欢那七个字~^_^~)

       HTML 5中的History API
对Web应用具有很大的熏陶。为了更便于的成立有作用的、对SEO友好的单页面应用,它移除了对散列值的依赖性。

下一篇:你在博客收录集吗?

History是有趣的,不是啊?在头里的HTML版本中,大家对浏览历史记录的操作相当有限。大家得以来回使用可以使用的不二法门,但那就是整套大家能做的了。

History API回顾

HTML5 History
API包括2个方法:history.pushState()和history.replaceState(),和1个事件:window.onpopstate。

干什么介绍History API ?

在那篇小说中,我们将明白HTML 5中History
API的发源。在此在此以前,咱们平常采纳散列值来改变页面内容,越发是这个对页面越发首要性的始末。因为从没刷新,所以对于单页面应用,改变其URL是不容许的。其余,当你改变URL的散列值值,它对浏览器的历史记录没有其他影响。

接下来,现在对此HTML 5的History
API来说,这么些都是足以擅自完成的,但是由于单页面应用没必要选拔散列值,它可能必要至极的付出脚本。它也允许我们用一种对SEO友好的法子确立新利用。别的,它能压缩带宽,然则该怎么申明呢?

在篇章中,我将用History API开发一个单页应用来验证上述的题材。

那也表示自己必须先在首页加载要求的资源。现在起先,页面仅仅加载须求的始末。换句话说,应用并不是一开始就加载了百分之百的内容,在乞请第一个应用内容时,才会被加载。

留意,您必要实施一些劳务器端编码只提供部分资源,而不是完整的页面内容。

javascript:historygo(-1) 网页已过期 怎解决

逾期了。。。解决吗啊。。HTML5有个history的api,你可以去看望
 

不过,利用HTML 5的History
API,大家可以更好的支配浏览器的历史记录了。例如:大家得以添加一条记下到历史记录的列表中,或者在尚未刷新时,可以立异地址栏的URL。

pushState

history.pushState(stateObject, title, url),包含多少个参数。

率先个参数用于存储该url对应的景观对象,该对象可在onpopstate事件中收获,也可在history对象中拿走。

其次个参数是标题,如今浏览器并未达成。

其四个参数则是设定的url。一般安装为相对路径,如果设置为绝对路径时索要确保同源。

pushState函数向浏览器的历史堆栈压入一个url为设定值的笔录,并改变历史堆栈的脚下指针至栈顶。

>
在那里作者利用历史堆栈和眼前指针,用以注解浏览器对历史记录的管理策略。文档中并不曾应用这样的词汇,作者为了更形象的介绍接口对浏览器历史记录的影响,使用那样的描述,如有不当之处请及时提议(不过当下以那套模型为根基的逻辑达成中没有出现悖论)。

浏览器协理

在写那篇作品的时候,各主流浏览器对History
API的支撑是杰出不易的,可以点击那里翻看其帮忙情形,这几个链接会告诉你协理的浏览器,并应用之前,总有美丽的实践来检测协理的特定功效。

为了用变成格局确定浏览器是不是帮助那么些API,可以用上面的一条龙代码检验:

XHTML

return !!(window.history && history.pushState);

1
return !!(window.history && history.pushState);

除此以外,我提出参考一下那篇作品:Detect Support for Various HTML5
Features.(ps:后续会翻译)

若是您是用的当代浏览器,可以用下边的代码:

XHTML

if (Modernizr.history) { // History API Supported }

1
2
3
if (Modernizr.history) {
    // History API Supported
}

假定你的浏览器不帮忙History
API,可以应用history.js代替。

html5 file api 上传文件

你可以到PHP100上面去咨询下 ~
在html5汉语件上传的话是将全体文件转换成base64编码然后在将文件存储的
而你的PHP程序可能不读base64把
 

5 History API的”前生今世”,api前生今世
原文:An Introduction To The HTML5 History API 译文:关于HTML 5 History
API 的介绍 译者:dwqs History是有趣…

 

replaceState

该接口与pushState参数相同,含义也如出一辙。唯一的不同在于replaceState是替换浏览器历史堆栈的脚下历史记录为设定的url。要求专注的是,replaceState不会转移浏览器历史堆栈的方今指针。

使用History

HTML 5提供了五个新点子:

1、history.pushState();               
2、history.replaceState();

两种格局都同意我们添加和换代历史记录,它们的行事规律相同并且可以增加数量一样的参数。除了艺术之外,还有popstate事件。在后文司令员介绍怎么拔取和哪些时候利用popstate事件。

pushState()和replaceState()参数一样,参数表明如下:

1、state:存储JSON字符串,可以用在popstate事件中。

2、title:现在多数浏览器不协理仍旧忽视这一个参数,最好用null代替

3、url:任意有效的URL,用于立异浏览器的地址栏,并不在乎URL是不是业已存在地址列表中。更首要的是,它不会再也加载页面。

五个方式的主要性分裂就是:pushState()是在history栈中添加一个新的条规,replaceState()是替换当前的记录值。假使您还对这个有迷惑,就用部分示范来注脚那些分化。

设若大家有四个栈块,一个标志为1,另一个标志为2,你有第二个栈块,标记为3。当执行pushState()时,栈块3将被添加到已经存在的栈中,由此,栈就有3个块栈了。

同等的假设情景下,当执行replaceState()时,将在块2的库房和停放块3。所以history的记录条数不变,也就是说,pushState()会让history的多少加1.

正如结实如下图:

美高梅开户网址 1

 

到此,为了操纵浏览器的历史记录,大家忽视了pushState()和replaceState()的轩然大波。可是假如浏览器计算了重重的不佳记录,用户可能会被重定向到那个页面,或许也不会。在那种场所下,当用户使用浏览器的迈入和落后导航按钮时就会暴发意料之外的题材。

固然当大家利用pushState()和replaceState()进行处理时,期待popstate事件被触发。但骨子里,处境并不是如此。相反,当您浏览会话历史记录时,不管您是点击前进或者后退按钮,依旧使用history.go和history.back方法,popstate都会被触发。

In WebKit browsers, a popstate event would be triggered after
document’s onload event, but Firefox and IE do not have this
behavior.(在WebKit浏览器中,popstate事件在document的onload事件后触发,Firefox和IE没有那种行为)。

为何介绍History API ?

onpopstate

该事件是window的特性。该事件会在调用浏览器的进化、后退以及执行history.forward、history.back、和history.go触发,因为这个操作有一个共性,即修改了历史堆栈的当下指针。在不更改document的前提下,一旦当前指针改变则会触发onpopstate事件。

Demo示例

HTML:

XHTML

<div class=”container”> <div class=”row”> <ul class=”nav
navbar-nav”> <li><a href=”home.html”
class=”historyAPI”>Home</a></li> <li><a
href=”about.html” class=”historyAPI”>About</a></li>
<li><a href=”contact.html”
class=”historyAPI”>Contact</a></li> </ul>
</div> <div class=”row”> <div class=”col-md-6″>
<div class=”well”> Click on Links above to see history API usage
using <code>pushState</code> method. </div>
</div> <div class=”row”> <div class=”jumbotron”
id=”contentHolder”> <h1>Home!</h1> <p>Lorem Ipsum
is simply dummy text of the printing and typesetting industry.</p>
</div> </div> </div> </div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="container">
    <div class="row">
        <ul class="nav navbar-nav">
            <li><a href="home.html" class="historyAPI">Home</a></li>
            <li><a href="about.html" class="historyAPI">About</a></li>
            <li><a href="contact.html" class="historyAPI">Contact</a></li>
        </ul>
    </div>
    <div class="row">
        <div class="col-md-6">
            <div class="well">
                Click on Links above to see history API usage using <code>pushState</code> method.
            </div>
        </div>
        <div class="row">  
            <div class="jumbotron" id="contentHolder">
                <h1>Home!</h1>
                <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            </div>
        </div>
    </div>
</div>

JavaScript:

JavaScript

<script type=”text/javascript”>
jQuery(‘document’).ready(function(){ jQuery(‘.historyAPI’).on(‘click’,
function(e){ e.preventDefault(); var href = $(this).attr(‘href’); //
Getting Content getContent(href, true);
jQuery(‘.historyAPI’).removeClass(‘active’); $(this).addClass(‘active’);
}); }); // Adding popstate event listener to handle browser back button
window.addEventListener(“popstate”, function(e) { // Get State value
using e.state getContent(location.pathname, false); }); function
getContent(url, addEntry) { $.get(url) .done(function( data ) { //
Updating Content on Page $(‘#contentHolder’).html(data); if(addEntry ==
true) { // Add History Entry using pushState history.pushState(null,
null, url); } }); } </script>

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
<script type="text/javascript">
    jQuery(‘document’).ready(function(){
 
        jQuery(‘.historyAPI’).on(‘click’, function(e){
            e.preventDefault();
            var href = $(this).attr(‘href’);
 
            // Getting Content
            getContent(href, true);
 
            jQuery(‘.historyAPI’).removeClass(‘active’);
            $(this).addClass(‘active’);
        });
 
    });
 
    // Adding popstate event listener to handle browser back button
    window.addEventListener("popstate", function(e) {
 
        // Get State value using e.state
        getContent(location.pathname, false);
    });
 
    function getContent(url, addEntry) {
        $.get(url)
        .done(function( data ) {
 
            // Updating Content on Page
            $(‘#contentHolder’).html(data);
 
            if(addEntry == true) {
                // Add History Entry using pushState
                history.pushState(null, null, url);
            }
 
        });
    }
</script>

Demo 1:HTML 5 History API – pushState

正史条目在浏览器中被统计,并且可以很不难的运用浏览器的上进和退化按钮。View
Demo 
(ps:你在点击demo1的选项卡时,其记录会被添加到浏览器的历史记录,当点击后退/前进按钮时,可以回到/跳到您前边点击的选项卡对应的页面)

Demo 2:HTML 5 History API – replaceState

历史条目在浏览器中被更新,并且无法使用浏览器的上扬和倒退按钮举行浏览。View
Demo 
(ps:你在点击demo1的选项卡时,其记录会被轮换当前浏览器的历史记录,当点击后退/前进按钮时,不可以回去/跳到你从前点击的选项卡对应的页面,而是回到/跳到您进来demo2的上一个页面)

        在那篇著作中,大家将理解HTML 5中History
API的来源。在此之前,大家平日选拔散列值来改变页面内容,尤其是那多少个对页面尤其主要的情节。因为尚未刷新,所以对于单页面应用,改变其URL是不容许的。其它,当您转移URL的散列值值,它对浏览器的历史记录没有其他影响。

History API与事务执行

最广泛的单页应用场景:列表页、商品详情页以及其内部的其他链接入口如图片页、评论页及其推荐其余商品详情页。以上提到的已经涉及到了4个独立业务逻辑页面(推荐的商品可复用商品详情页逻辑),分别是:列表、详情、图片详情和评论。将那4个页面合并到一个页面中,那就是最简易的SPA。为了用户的好好体验,必须设计合理的相互逻辑,最直观的就是浏览器(或手机app、微信公众号)的后退前进必须符合业务逻辑特点。因而,那就提到到了History
API的施用,也牵涉到浏览器的历史记录管理。

美高梅开户网址 2

上图为现实的逻辑示意图。在列表页,点击其中一个商品,那里是商品1,进入详情页。详情页蕴涵了该商品的轮播图、商品的图形详情入口、评论入口和引进的其余商品进口。接下来开展如下操作:进入图片详情页,后退至详情页再进入评论页;后退至商品1详情页再由推荐商品进口进去商品9详情页,同样在商品9详情页进入图片详情页和评论页,再后退至商品9详情页;由推荐商品进口进去商品34详情页,再进行类似操作。最终有限支撑在货物34图片详情页或评头品足页可以万事大吉后退至最初的商品列表页。

>
上文中加粗的“后退”,意味着使用浏览器后退按钮,或者接纳手机自带的回来,再或者拔取页面上提供的落后按钮。

如此一个很细小的需求,不过假如真的甩手去做却不是那么简单。仅仅按照History
API的2个函数和1个事件去盲目标品味达成,那属于以管窥天,鲁棒性不高。不知道浏览器的历史记录管理策略,不打听当前页面的历史记录数量,此种情形若要落成上述情景就稍微麻烦。所以在切实出手写作业代码以前,需要搞懂History的pushState和replaceState具体什么影响历史记录栈。

小结(ps:喜欢这多个字~^_^~)

HTML 5中的History API
对Web应用具有很大的影响。为了更易于的创设有效能的、对SEO友好的单页面应用,它移除了对散列值的借助。

赞 1 收藏
评论

美高梅开户网址 3

        然后,现在对此HTML 5的History
API来说,那一个都是可以随意完结的,不过由于单页面应用没必要采纳散列值,它或许需求万分的开销脚本。它也允许大家用一种对SEO友好的办法确立新利用。别的,它能裁减带宽,可是该怎么声明呢?

探索浏览器历史记录策略与History API的关系

鉴于浏览器并未针对各类页面的历史记录提供切实访问的接口,因而有着的测试都是黑盒。可是在运动端的中,大都是webkit内核,其webcore的切实可行落实也都类似,因此该节得出的结论完全可以在运动端接纳。

就算不能访问当前页的野史记录栈,但是浏览器却提供了history.length属性,它标志了如今历史记录栈的个数。该值会支持大家更好地剖析History
API对历史记录栈的震慑。

美高梅开户网址 4

上图为测试实例。其中白色箭头意味着点击该链接并推行pushState操作(即操作1),粉青色箭头则执行浏览器后退,褐色的圆点为历史记录栈中的当前指针,而各种项则为历史记录栈,历史记录的个数则为其子项的多寡。

开端在首先个搜索列表页,执行操作1后历史堆栈数量扩充,当前指针上移一位至26788.html;
同理在实践3次操作1,历史堆栈递增3个,当前指针仍在栈顶,即78099.html;
此后进展浏览器后退,历史堆栈数量不变,当前指针下移一位至8819.html;
在此间再进行操作1,栈顶元素改变,当前指针移至栈顶,历史堆栈数量不变;
继续执行操作1,栈顶元素改变,指针移至栈顶,历史堆栈数量加一;
执行浏览器后退,栈顶元素不变,指针下移一位至8128.html,历史堆栈数量不变;
执行浏览器后退,栈顶元素不变,指针下移一位至8819.html,历史堆栈数量不变;
执行浏览器后退,栈顶元素不变,指针下移一位至8128.html,历史堆栈数量不变;
执行浏览器后退,栈顶元素不变,指针下移一位至26788.html,历史堆栈数量不变;
执行操作1,栈顶元素变为9721.html,指针上移至栈顶,历史堆栈数量改为3;
执行操作1,栈顶元素变为8387.html,指针上移至栈顶,历史堆栈数量变成4;
执行浏览器后退,栈顶元素不变,指针下移一位至9721.html,历史堆栈数量不变;
执行浏览器后退,栈顶元素不变,指针下移一位至26788.html,历史堆栈数量不变;
执行浏览器后退,栈顶元素不变,指针下移一位至search.html,历史堆栈数量不变;
执行操作1,栈顶元素变为xxx.html,指针上移至栈顶,历史堆栈数量变成2; …

迄今截至,实验停止。就算那里唯有列出了这几个测试用例,不过其实作者做了更加多更扑朔迷离的测试,并且平台涉及了pc和移动端的浏览器、微信和原生webview,结果都同一。这一种类测试注脚了很多难题,总计之一句话则是:

浏览器针对各样页面维护一个History栈。执行pushState函数可压入设定的url至栈顶,同时修改当前指针;
当执行back操作时,history栈大小并不会变动(history.length不变),仅仅移动当前指针的职位;
若当前指针在history栈的中级地方(非栈顶),此时执行pushState会改变history栈的大小。
统计pushState的法则,可发现眼前指针在history栈顶部时实施pushState,会大增history栈大小;若current指针不在栈顶则会在如今指针所在地点添加项。执行back操作并不改动history栈大小,因而得以透过back和forward在当前高低的history栈中随意移动。

左右那些原理,就驾驭如何保证历史记录,就领悟在如何意况下需要pushState。回到最初的急需,产品经营规定从商品34的评论页,按后退按钮可以抵达最初的列表页,可是他并从未详细规定何将来退。在此处就会有2中完成方式:

  • 每五次后退,会再次回到上次的访问地点。如,在商品34的褒贬页,会后退至商品34的详情页,再后退则会回去商品9的详情页,直至回到列表页。
  • 一起维护三层历史记录,第一层(栈底)为列表页,第二层为详情页,第三层(栈顶)为评价页或图表详情页。在该种落成下,由货物34的评论页第二回后退至商品34的详情页,第二次后退至列表页。

本着第一种,其实落成最为不难,因为那完全是由浏览器默许控制历史记录堆栈,而我辈只需在适度的空子调用pushState将url插入到仓库,然后在onpopstate处理函数中监听对应的时刻即可:

window.add伊芙ntListener(‘popstate’, function (e) {
console.log(‘popstate’) // 后退(前进)至商品详情页,异步加载数据并渲染
if(e.state && e.state.indexOf(‘/shop/sku/’) !== -1){
ajaxDetail(e.state,true); }else //
后退(前进)至评论页,异步加载数据渲染 if(e.state &&
e.state.indexOf(‘/shop/comment/commentList.html’) !== -1){
ajaxComment(e.state,true); }else //
后退(前进)至图片详情页,异步加载数据渲染 if(e.state &&
e.state.indexOf(‘/shop/item/pictext/’) !== -1){ ajaxPic(e.state,true);
}else // 后退(前进)至列表页,隐藏浮层 if(e.state &&
e.state.indexOf(‘/search/’) !== -1){ // 隐藏spa的浮层
$(‘.spa-container’).css(‘zIndex’,’-1′); } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
window.addEventListener(‘popstate’, function (e) {
    
    console.log(‘popstate’)
    // 后退(前进)至商品详情页,异步加载数据并渲染
    if(e.state && e.state.indexOf(‘/shop/sku/’) !== -1){
      ajaxDetail(e.state,true);  
    }else
    // 后退(前进)至评论页,异步加载数据渲染
    if(e.state && e.state.indexOf(‘/shop/comment/commentList.html’) !== -1){
      ajaxComment(e.state,true);
    }else
    // 后退(前进)至图片详情页,异步加载数据渲染
    if(e.state && e.state.indexOf(‘/shop/item/pictext/’) !== -1){
      ajaxPic(e.state,true);
    }else
    // 后退(前进)至列表页,隐藏浮层
    if(e.state && e.state.indexOf(‘/search/’) !== -1){
      // 隐藏spa的浮层
      $(‘.spa-container’).css(‘zIndex’,’-1′);
    }
    
  });

本着第三种完毕,则是本文的基本点。毕竟,由浏览器默许维护的野史堆栈在一些事情场景中并不合作,由此必要开发者自己维护一个历史记录栈。在此次完结中,由于一起涉及4张页面的呈现,因而我们设定了3层历史堆栈,那很好了然。

为了创设那样的野史记录栈,在主页面(即列表页)中须求额外添加两条历史记录。那是出于默许打开列表页时,当前页面的url已参预历史记录栈中,

function push(state){ history.pushState(state, null, location.pathname +
location.search); } // ‘abc’用于标示起始列表页
history.replaceState(‘abc’,null,location.pathname + location.search) //
压入两条历史记录 push(); push();

1
2
3
4
5
6
7
8
9
function push(state){
    history.pushState(state, null, location.pathname + location.search);
  }
  // ‘abc’用于标示初始列表页
  history.replaceState(‘abc’,null,location.pathname + location.search)
  
  // 压入两条历史记录
  push();
  push();

这么,打开列表页后就会创立3个历史记录,并且这3个历史记录的url都为列表页的url,那与背后的操作并无影响。

在列表页中打开详情页,要求做额外的拍卖。由于按照大家规划的野史记录栈,第二层应该为详情页,而此时在伊始化后,历史记录栈的此时此刻指针已指向栈顶元素,由此须求将方今指针下移一位。这里就要求history.back来成功。

$(‘.item-list’).on(‘click’,’a’,handler); // 异步加载详情数据 var handler
= function(e,isScrollXClick){ var a = this;
ajaxDetail($(a).attr(‘href’),isScrollXClick); return false; }; var
isScrollXClick; /** * @params: url 请求路径 isScrollXClick:
是不是点击推荐商品 * */ var ajaxDetail = function(url,isScrollXClick){
$.ajax({ url: ‘/api’ + url, success: function(data){ … …
if(!isScrollXClick){ console.log(‘I am back!’) // 在代码中开展back or
forward并不会立即起身popstate事件,以v8引擎为例,在实践back之后 //
的大体18us之后会接触事件,而此时若是及时通过replaceState修改url则会造成破产,修改的是
// history stack栈顶的url. // 那里透过异步执行replaceState包容history.back(); } // 异步触发 setTimeout(function(){
history.replaceState(url, null, url); }) //
针对推荐栏的货色,循环绑定事件,此处用事件代理优化
$(‘#J_PDSlider’).on(‘click’,’a’,function(e){ isScrollXClick = 1;
handler.call(this,e,isScrollXClick); return false; }); }, error:
function(xhr, type){ alert(‘Ajax error!’) } }) };

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
47
48
49
50
$(‘.item-list’).on(‘click’,’a’,handler);
 
// 异步加载详情数据
var handler = function(e,isScrollXClick){
    var a = this;
    ajaxDetail($(a).attr(‘href’),isScrollXClick);
    return false;
};
 
var isScrollXClick;
  /**
   * @params: url 请求路径 isScrollXClick: 是否点击推荐商品
   *
   */
  var ajaxDetail = function(url,isScrollXClick){
 
     $.ajax({
      url: ‘/api’ + url,
      success: function(data){
        …
        …
        if(!isScrollXClick){
          console.log(‘I am back!’)
 
          // 在代码中进行back or forward并不会立即出发popstate事件,以v8引擎为例,在执行back之后
          // 的大概18us之后会触发事件,而此时如果立即通过replaceState修改url则会造成失败,修改的是
          // history stack栈顶的url.
          
          // 这里通过异步执行replaceState兼容
          history.back();      
          
        }
          
        // 异步触发
        setTimeout(function(){
          history.replaceState(url, null, url);
        })
 
        // 针对推荐栏的商品,循环绑定事件,此处用事件代理优化
        $(‘#J_PDSlider’).on(‘click’,’a’,function(e){
          isScrollXClick = 1;
          handler.call(this,e,isScrollXClick);
          return false;
        });
      },
      error: function(xhr, type){
        alert(‘Ajax error!’)
      }
     })
  };

在此处完毕,通过isScrollXClick变量判断是还是不是点击的是引进商品,假如不是则须求履行back操作,下移指针。此时指针是指在其次层,不过浏览器和第二层历史记录的url仍为开始化设定的url,因而需求修改,在此处异步修改当前url。

为此异步执行replaceState,是出于webkit触发popState事件决定的。在代码中履行history.back
或者history.forward,并不会即刻回去,也不会立时触发popState事件。由于没有读书webkit的源码,由此未能推断执行back或者forward后实际必要格外做怎么着操作,它们中间有着10us级其余间隔,由此那里必须利用set提姆eout完毕异步转移url。

在切实成本进程中,那个题材烦扰着小编好几天,终于在三遍调试进度中发现浏览器url的改动,才联想到可能是由事件触发的时刻差导致。

对于图片详情和评价的逻辑处理,则和上文类似,无需多言。

最后五次后退须要回到列表页,而在起先化阶段大家给列表页设置了state为“abc”,特殊的标志该路由,由此在popState事件处理中,大家就可以依照该项回到开始页:

window.addEventListener(‘popstate’, function (e) { if(e.state &&
e.state.indexOf(‘/shop/sku/’) !== -1){ ajaxDetail(e.state,true); }else
if(e.state && e.state.indexOf(‘abc’) !== -1){ // 隐藏spa的浮层
$(‘.spa-container’).css(‘zIndex’,’-1′); push(); push(); } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
window.addEventListener(‘popstate’, function (e) {
 
    if(e.state && e.state.indexOf(‘/shop/sku/’) !== -1){
      ajaxDetail(e.state,true);  
    }else if(e.state && e.state.indexOf(‘abc’) !== -1){
      // 隐藏spa的浮层
      $(‘.spa-container’).css(‘zIndex’,’-1′);
      
      
      push();
      push();
    }
    
    
  });

若果回到早先页,隐藏浮层,同时在实施2次push操作。依据上节发现的法则,在起始页执行2次push操作,会在现阶段指针位置再一次添加2个历史记录,当前指针指向栈顶元素,历史记录栈的数量不变,仍为3。那样就完了了简便易行的由开发者自定义维护历史堆栈的spa系统。

        在小说中,我将用History API开发一个单页应用来表达上述的难题。

回顾

因而会写这篇文章完全是由于偶然,由于实在项目标各个需求大家不应有一味将眼光停留在利用API的范围上。此外,在支付进度中蒙受难以解决的标题,必要提出各个合理的设想并用详细的实验证实,在赢得相对应的结论后须求动用该结论去例证其他场景,那样才能担保解决方案的可相信性。近期互联网上或者书籍中从未提供其余手动维护历史记录堆栈的法子,也未明确指出History
API与浏览器历史记录之间怎么样影响,由此本文对于目的在于利用History
API完结spa的开发者而言依然略微指引意义的。

打赏帮助自己写出越来越多好文章,谢谢!

打赏小编

       
那也表示自己必须先在首页加载须要的资源。现在初叶,页面仅仅加载必要的情节。换句话说,应用并不是一开始就加载了方方面面的始末,在伸手第三个使用内容时,才会被加载。

打赏帮忙我写出更加多好小说,谢谢!

美高梅开户网址 5

1 赞 7 收藏
评论

注意,您需求执行一些服务器端编码只提供部分资源,而不是完整的页面内容。

有关小编:欲休

美高梅开户网址 6

前端自由人
个人主页 ·
我的稿子 ·
1 ·
 

美高梅开户网址 7

 

浏览器帮忙

         在写那篇文章的时候,各主流浏览器对History
API的支持是可怜不易的,可以点击那里查看其匡助景况,那些链接会告诉你协理的浏览器,并选用往日,总有杰出的施行来检测协理的特定成效。

        
为了用变成形式确定浏览器是或不是接济这些API,可以用上边的一条龙代码检验:

return !!(window.history && history.pushState);

 

         别的,我提议参考一下那篇小说:Detect Support for Various HTML5
Features.(译文:)

         即使您是用的当代浏览器,可以用下边的代码:

if (Modernizr.history) {
    // History API Supported
}

 

         假设你的浏览器不协理History
API,可以接纳history.js代替。

 

使用History

        HTML 5提供了五个新措施:

              1、history.pushState();               
2、history.replaceState();

       
三种办法都同意大家抬高和立异历史记录,它们的做事原理相同并且可以加上数量同样的参数。除了艺术之外,还有popstate事件。在后文中将介绍怎么使用和曾几何时使用popstate事件。

        pushState()和replaceState()参数一样,参数说明如下:

              1、state:存储JSON字符串,可以用在popstate事件中。

             
2、title:现在半数以上浏览器不扶助照旧忽视这么些参数,最好用null代替

             
3、url:任意有效的URL,用于更新浏览器的地址栏,并不在乎URL是或不是曾经存在地址列表中。更要紧的是,它不会再度加载页面。

       
四个格局的要紧差异就是:pushState()是在history栈中添加一个新的条条框框,replaceState()是替换当前的记录值。要是你还对那个有迷惑,就用一些演示来表达这些分化。

       
借使大家有四个栈块,一个标志为1,另一个符号为2,你有首个栈块,标记为3。当执行pushState()时,栈块3将被添加到已经存在的栈中,由此,栈就有3个块栈了。

       
同样的借使情景下,当执行replaceState()时,将在块2的仓库和停放块3。所以history的记录条数不变,也就是说,pushState()会让history的多寡加1.

        相比结实如下图:

美高梅开户网址 8

       
到此,为了操纵浏览器的历史记录,大家忽视了pushState()和replaceState()的轩然大波。可是如若浏览器总计了众多的不善记录,用户可能会被重定向到这几个页面,或许也不会。在那种景观下,当用户使用浏览器的腾飞和退化导航按钮时就会爆发意料之外的标题。

       
尽管当大家运用pushState()和replaceState()进行处理时,期待popstate事件被触发。但实在,情形并不是如此。相反,当您浏览会话历史记录时,不管您是点击前进或者后退按钮,依旧使用history.go和history.back方法,popstate都会被触发。

美高梅开户网址,In WebKit browsers, a popstate event would be triggered after
document’s onload event, but Firefox and IE do not have this
behavior.(在WebKit浏览器中,popstate事件在document的onload事件后触发,Firefox和IE没有那种行为)。

      

Demo示例

       HTML:

<div class="container">
    <div class="row">
        <ul class="nav navbar-nav">
            <li><a href="home.html" class="historyAPI">Home</a></li>
            <li><a href="about.html" class="historyAPI">About</a></li>
            <li><a href="contact.html" class="historyAPI">Contact</a></li>
        </ul>
    </div>
    <div class="row">
        <div class="col-md-6">
            <div class="well">
                Click on Links above to see history API usage using <code>pushState</code> method.
            </div>
        </div>
        <div class="row">   
            <div class="jumbotron" id="contentHolder">
                <h1>Home!</h1>
                <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
            </div>
        </div>
    </div>
</div>

 

       JavaScript:

<script type="text/javascript">
    jQuery('document').ready(function(){

        jQuery('.historyAPI').on('click', function(e){
            e.preventDefault();
            var href = $(this).attr('href');

            // Getting Content
            getContent(href, true);

            jQuery('.historyAPI').removeClass('active');
            $(this).addClass('active');
        });

    });

    // Adding popstate event listener to handle browser back button 
    window.addEventListener("popstate", function(e) {

        // Get State value using e.state
        getContent(location.pathname, false);
    });

    function getContent(url, addEntry) {
        $.get(url)
        .done(function( data ) {

            // Updating Content on Page
            $('#contentHolder').html(data);

            if(addEntry == true) {
                // Add History Entry using pushState
                history.pushState(null, null, url);
            }

        });
    }
</script>

 

          Demo 1:HTML 5 History API – pushState

正史条目在浏览器中被总计,并且可以很不难的使用浏览器的前进和落后按钮。View
Demo 
(ps:你在点击demo1的选项卡时,其记录会被添加到浏览器的历史记录,当点击后退/前进按钮时,可以回去/跳到您后边点击的选项卡对应的页面)

Demo 2:HTML 5 History API – replaceState

历史条目在浏览器中被更新,并且无法运用浏览器的发展和退化按钮举办浏览。View
Demo 
(ps:你在点击demo1的选项卡时,其记录会被替换当前浏览器的历史记录,当点击后退/前进按钮时,不得以回到/跳到您前边点击的选项卡对应的页面,而是再次来到/跳到你进去demo2的上一个页面)

小结(ps:喜欢那多个字~^_^~)

       HTML 5中的History API
对Web应用具有很大的影响。为了更易于的创立有作用的、对SEO友好的单页面应用,它移除了对散列值的借助。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图