avatar

HTML5 History API + Ajax (Pjax) 实现友好的局部刷新

用过Github的同学一定对其Ajax局部刷新感到神奇吧,既实现了局部刷新,又修改了浏览器地址,并却做到了前进后推的效果
这其实是HTML5 History API实现的效果 其技术叫 pjax 很蛋疼的名字 pushState + ajax

好吧开始吧事因说下~
近期要做套G+的Wordpress主题,所以查阅了很多资料来帮助SEO
然后查着查着 我看到了HTML5 标签, 看着看着, 我看到了 HTML5 history
然后继续蛋疼, 然后就开始研究 pjax 了 = -
PS: 在G+中也大量运用了该技术啊!

以上全部是吐槽 正文从这里开始!

FF5发布会的时候,FF的工程师展示了一种HTML5的新技术,特别的提及了Github所采作用这种技术.
十分的友好,个人认为是完美解决了Ajax对搜索引擎不友好 这个万恶的问题.

简单的说下用到的技术(已知)
JQuery HTML5 Ajax
JQuery用来委托所有的超链接的click事件
HTML5 用了History API 的 pushState 方法
Ajax 这个我无法说明 = -

通过Chrome的Developer Tools可以查看到Github中超链接访问的页面都会带一个slide=1的参数

如我们访问 https://github.com/Hypnusds/dopicasa/blob/master/README 这个文件时
浏览器直接访问 是访问以上那个地址
但是在Github中访问是,我们访问的是 https://github.com/Hypnusds/dopicasa/blob/master/README?slide=1
它会返回一个局部HTML 这就是我们通常使用的Ajax技术

*实现思路

用过JQuery的live方法委托需要使用到Ajax的超链接,重写其click事件

this.live('click', function(event){
/* 代码 */
}

请不要使用bind方法,用委托比较好~~ 不然每次Ajax加载完成后,你再bind一次也是可以的 我是不推荐!
Github是将所有class为js-slide-to的全部委托了局部刷新事件

#关于增加参数 输出不同结果,我就不说明了,只是建议大家多使用各种设计模式吧.

然后需要做的事情就很简单, 使用API来修改浏览器地址,push一个state对象即可
在说之前,我先介绍下 HTML5 history对象的两个新方法

history.pushState(data, title [, url]) Pushes the given data onto the session history stack with the specified title and, if provided, URL. The data is treated as opaque by the DOM; you may specify any JavaScript object that can be serialized into JSON format.
history.replaceState(data, title [, url]) Updates the most recent entry on the history stack to have the specified data, title, and, if provided, URL. The data is treated as opaque by the DOM; you may specify any JavaScript object that can be serialized into JSON format.

咱的英语很烂 大概解释下吧 一个是push State对象,URL,Title到history stack
第二个是修改!

*参数说明

state object — The state object is a JavaScript object which is associated with the new history entry created by pushState(). Whenever the user navigates to the new state, a popstate event is fired, and the state property of the event contains a copy of the history entry's state object.

The state object can be anything that you can pass to JSON.stringify. Because Firefox saves state objects to the user's disk so they can be restored after the user restarts her browser, we impose a size limit of 640k characters on the JSON representation of a state object. If you pass a state object whose JSON representation is larger than this to pushState(), the method will throw an exception. If you need more space than this, you're encouraged to use sessionStorage and/or localStorage.

title — Firefox currently ignores this parameter, although it may use it in the future. Passing the empty string here should be safe against future changes to the method. Alternatively, you could pass a short title for the state to which you're moving.

URL — The new history entry's URL is given by this parameter. Note that the browser won't attempt to load this URL after a call to pushState(), but it might attempt to load the URL later, for instance after the user restarts her browser. The new URL does not need to be absolute; if it's relative, it's resolved relative to the current URL. The new URL must be of the same origin as the current URL; otherwise, pushState() will throw an exception. This parameter is optional; if it isn't specified, it's set to the document's current URL.

现在我们要做的是修改浏览器URL,并且push一条记录给history stack

*实现方法

因为我们是用过委托对象来激活事件的,所以我们当然可以获取到委托对象的url

history.pushState(state, title, url);

浏览器后退前进时候会触发onpopstate事件,这个时候,我们可以得到state对象
(state只是个普通的数组而已 FF说他只支持640K以下, 如果是大数据的话用sessionStorage或者localStorage)

if (history && history.pushState) {
  $(window).bind('popstate', function(event){
  }
}

event.state即可获取state
根据测试 第一次加载页面的时候 也会触发onpopstate, 所以加个flag可以避免第一处理程序逻辑

title这是个十分纠结的参数啊 我没发现那里能用它 真的~

replaceState目前研究下来 没发现需要使用它的地方 但是pjax源码中使用到了它,蛋疼.
算了,到这里为止, 我所需要达到的效果已经搞定了.就这样吧!!

备注

Ajax请自带一个hash码,不然没的治!
尽量不要使用全局live
IE那货不支持! 目前测试IE9 不支持~

想做个Demo,但是咱的G+主题还没搞定,先搁置吧~~

*参考文献

MSD window.histor: https://developer.mozilla.org/en/dom/window.history
Pjax: https://github.com/defunkt/jquery-pjax

*推荐资源

Github的js: http://db.tt/B0Q0Yb8
Pjax源码: https://github.com/defunkt/jquery-pjax/blob/master/jquery.pjax.js

Comments ( 2 ) Trackbacks ( 0 ) Leave a Reply
  1. avatar
  2. avatar
    很多东西出来几年了,才开始搞,博主11年就已经在上手了,真是感觉自愧不如啊~ 前几天也写了一篇相关的http://barretlee.com/history-api-in-html5/
  1. No trackbacks yet.

    目前尚无任何 trackbacks 和 pingbacks.

    トラックバックはまだありません。

  • ☆*:.。. o(≧▽≦)o .。.:*☆
  • _(:з」∠)_
  • ♪(´ε` )
  • ψ(`∇´)ψ
  • (-_-#)
  • (=´∀`)人(´∀`=)
  • \(//∇//)\
  • ♪(*^^)o∀*∀o(^^*)♪
  • (((o(*゚▽゚*)o)))
  • (´・_・`)
  • σ(^_^;)
  • ( *`ω´)
  • (ノ`Д´)ノ
  • (( _ _ ))..zzzZZ
  • ( ̄▽ ̄)
  • ヽ(`Д´#)ノ
  • ((((;゚Д゚)))))))
  • (>_<)
  • (T_T)
  • ( T_T)\(^-^ )
  • ε=ε=ε=ε=ε=ε=┌(; ̄◇ ̄)┘