再详解history.pushState和history.replaceState以及page ajax的实现

广告位招租
扫码页面底部二维码联系

在之前的文章《原创内容,盗版必究。ajax无刷新加载页面,结合histor本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.nety.state修改url》中,我详细解释了history.pus本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】hState、history.repla原创内容,盗版必究。原创内容,盗版必究。ceState、history.stat【转载请注明来源】【本文首发于唐霜的博客】e以及window.popstate这四本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】个关键元素,并试图建立一个合理的ajax著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】无刷新更换URL的页面加载方式。但那之后【版权所有】唐霜 www.tangshuang.net【转载请注明来源】,我遇到一个比较复杂的问题,集中在sta本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】te的内容上,本文则来详解state这个著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】要素。

著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】

state是什么?【访问 www.tangshuang.net 获取更多精彩内容】

【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】【作者:唐霜】

状态对象(state object)本文作者:唐霜,转载请注明出处。 — 一个JavaScript对象,与用本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】pushState()方法创建的新历史记著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。录条目关联。无论何时用户导航到新创建的状【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】态,popstate事件都会被触发,并且【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net事件对象的state属性都包含历史记录条【作者:唐霜】未经授权,禁止复制转载。目的状态对象的拷贝。(原文【版权所有,侵权必究】未经授权,禁止复制转载。

本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。

说白了,state就是我们用于保存到hi【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。story序列中的一个数据集合。我们可以原创内容,盗版必究。本文作者:唐霜,转载请注明出处。在pushState之前,先构建自己的s【本文首发于唐霜的博客】【本文受版权保护】tate,里面可以存放很多我们在监听wi未经授权,禁止复制转载。【原创内容,转载请注明出处】ndow.popstate事件时所需要的本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。东西。

【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net

例如,我们用代码来看:【关注微信公众号:wwwtangshuangnet】

本文版权归作者所有,未经授权不得转载。【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】【原创内容,转载请注明出处】
var state = {
  title: title,
  url: url,
  content: $('body').html(),
  prev: window.location.href,
  time: (new Date()).getTime()
};
history.pushState(state, title, url);

上面title和url两个值是其他地方已【版权所有,侵权必究】【未经授权禁止转载】经准备好的。通过上面这段代码,在hist未经授权,禁止复制转载。【未经授权禁止转载】ory序列中就多出一个state,并且可【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。以通过window.popstate识别著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。

本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】【本文首发于唐霜的博客】

而在window.popstate的监听未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net动作中,我们可以这样去做:

【本文受版权保护】本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。
window.onpopstate = function(event) {
  var state = history.state; // 等价于 
  var state = event.state;
  if(state && state.content) $('body').html(state.content);
};

当点击浏览器的前进或后退按钮时,pops【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】tate事件被触发,浏览器会到histo【原创不易,请尊重版权】【本文受版权保护】ry序列中去找到上一个或下一个state【作者:唐霜】【本文首发于唐霜的博客】,并且将这个state放到event.s本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。tate中。这个时候,该state就是当【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net前浏览器所显示的页面所使用的state了【未经授权禁止转载】【本文受版权保护】,所以使用history.state可以【未经授权禁止转载】本文版权归作者所有,未经授权不得转载。读取到同样的内容。

【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】【原创不易,请尊重版权】【关注微信公众号:wwwtangshuangnet】

而这个时候,该state中,正好保存着我转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。们在pushState时,保存到cont【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.netent内容,直接使用它即可。为了实现ti【版权所有,侵权必究】【本文首发于唐霜的博客】tle,css,js之类的进一步重载,你著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。还可以做更多的内容保存和逻辑处理。

【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。原创内容,盗版必究。

从上面可以看到,当我们在使用pushSt【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.netate和popstate时,可以在脑海中【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】先想象一个history序列,通过pus【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。hState加入一个新state到序列中著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】,通过history.state取出当前【作者:唐霜】【原创内容,转载请注明出处】屏幕显示区域所需要的state。

【未经授权禁止转载】【本文首发于唐霜的博客】【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】

replaceState和pushSta转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】te的区别

【原创内容,转载请注明出处】【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net

虽然从上面的讲解中,我们大致掌握了sta【原创内容,转载请注明出处】【本文受版权保护】te序列的问题,但是,我们还有一个点没有著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。讲到,那就是改变url。毫无疑问,我们知【原创内容,转载请注明出处】原创内容,盗版必究。道通过replaceState可以无刷新本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】页面改变url。

原创内容,盗版必究。本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】【原创内容,转载请注明出处】
history.replaceState(state,title,url);

其中,state,title,url都是本文版权归作者所有,未经授权不得转载。【作者:唐霜】我们事先准备好的。其中,要点就是url,【未经授权禁止转载】【作者:唐霜】如果我们仅仅希望实现URL的变化,甚至可【转载请注明来源】未经授权,禁止复制转载。以做下面这个实验:

【原创不易,请尊重版权】【版权所有,侵权必究】【转载请注明来源】原创内容,盗版必究。
history.replaceState(null,null,'/test.html');

把这段代码加入到页面后,观察url的变化【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】。实际上,整个页面没有发生任何变动,唯独【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】url改变了。

【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net【未经授权禁止转载】【原创不易,请尊重版权】

这个时候,我们回头来看replaceSt【原创不易,请尊重版权】【版权所有,侵权必究】ate之后,state的一些变化。通过下原创内容,盗版必究。【原创内容,转载请注明出处】面这段代码来试验:

【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】【版权所有,侵权必究】
console.log(history.state); // 得到一个内容丰富的state内容
history.replaceState(null,null,'/test.html');
console.log(history.state); // 得到null

这说明replaceState将对当前显本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。示界面对应的state发生作用,甚至替换著作权归作者所有,禁止商业用途转载。【作者:唐霜】state的内容,这是一个会产生负影响的本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。操作,实际上,我们希望通过pushSta【未经授权禁止转载】【本文首发于唐霜的博客】te将一个配置好的state加入到his转载请注明出处:www.tangshuang.net【作者:唐霜】tory序列中,但是replaceSta原创内容,盗版必究。【本文首发于唐霜的博客】te改变了我们加入到序列中的state的【作者:唐霜】【未经授权禁止转载】内容。因此,我们必须保证replceState著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。的时候,所传入的state参数所我们想要【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。使用的state的内容。这个很难理解,我们用一张图来解释:著作权归作者所有,禁止商业用途转载。

本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。

historyState

【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【转载请注明来源】

上图中,1是原本的history序列,我原创内容,盗版必究。【转载请注明来源】们在阅读到某个界面到时候,执行pushS【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。tate操作,使history序列变成了【未经授权禁止转载】【未经授权禁止转载】2的状态,再对pushState的sta本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.nette执行replaceState后,变成【转载请注明来源】未经授权,禁止复制转载。了3的状态。从2变为3这个过程,把原本的【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】state修改了,我们要想清楚,我们是要【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net把{title,content}放入hi【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。story还是把{name,number未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。}放入history,如果是前者,那么就【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。要在replaceState的时候,格外【版权所有,侵权必究】【版权所有,侵权必究】小心。

【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】

配合ajax实现无刷新切换url的页面跳著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。

未经授权,禁止复制转载。【作者:唐霜】【本文受版权保护】【本文受版权保护】

通过上面这些讲解,我们大致可以总结出如下【本文首发于唐霜的博客】原创内容,盗版必究。一些思路:

本文作者:唐霜,转载请注明出处。原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。

1.ajax加载新页面2.加载完后,通过未经授权,禁止复制转载。【本文首发于唐霜的博客】pushState记录历史,通过repl转载请注明出处:www.tangshuang.net【本文受版权保护】aceState切换url,页面无刷新,【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】但url变了3.通过window.pop【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】state实现点击前进后退时,切换到之前转载请注明出处:www.tangshuang.net【转载请注明来源】的页面内容

【未经授权禁止转载】【原创内容,转载请注明出处】原创内容,盗版必究。
$('a[href]').on('click',function(e) {
  e.preventDefault();
  var $this = $(this),href = $this.attr('href');
  if($this.attr('disable-ajax') !== undefined) return true;
  if(href.indexOf('javascript') === 0) return false;
  if(href.indexOf('http') === 0 && href.indexOf(window.location.host) < 0) return true;
  $.get(href,function(html) {
    var title = $(html).find('title').html(), content = $(html).find('#content');
    $('title').html(title);
    $('#content').html(content);
    var state = { // 准备用于push的state
      title: title,
      url: href,
      selector: '#content',
      content: content,
      prev: window.location.href,
      time: (new Date()).getTime()
    };

    if(href != state.prev) history.pushState(state, title, href);
    history.replaceState(state, title, href);
  });
});

$(window).on("popstate", function() {
  var state = history.state;
  if(!state || !state.selector) { // 如果不存在state,则说明是第一次进入该页,就没有必要进行前进或后退操作
    return;
  }
  $(state.selector).html(state.content);
  $('title').html(state.title);

  history.replaceState(state,state.title,state.url);
});

将上面这段代码放到你的jquery代码中【转载请注明来源】原创内容,盗版必究。,注意要放到$(document).re本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.netady()中。我们这里有一个规定,就是使【本文受版权保护】【原创内容,转载请注明出处】用#content作为选择器,抓取和替换【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】的内容仅限于#content区域。这样的【转载请注明来源】本文作者:唐霜,转载请注明出处。话,你的页面上的菜单、边侧栏都没有变化。未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net所以,最好可以把选择器范围扩大,并增加一【未经授权禁止转载】【关注微信公众号:wwwtangshuangnet】些页面变化的动作。

【本文首发于唐霜的博客】【未经授权禁止转载】【本文首发于唐霜的博客】

2016-03-25 19307 ,

为价值买单,打赏一杯咖啡

本文价值193.07RMB