黄聪:Pjax 无刷新开发web,更好用户体验

2019年11月25日 阅读数:23
这篇文章主要向大家介绍黄聪:Pjax 无刷新开发web,更好用户体验,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

什么Ajax、Pjax、Njax。。。神马玩意? 有Njax吗? 木有。。。不过真有Pjax!!javascript

其实pjax就是用到了html5的新history api: pushState和replaceState。若是浏览器不支持,会自动降级为普通http访问,跟正常a连接同样css

具体啥区别?先视觉通感感觉下!!上图:html

 

一、普通的http切换页面的请求方式,闪烁、白屏、卡顿、加载等,就是完整加载一坨页面嘛joy,又慢又挫的,就像如花姑娘:html5

1.jpg

 

二、经过Ajax来开发页面,只加在部分数据,没有切换和闪烁,清新宜人哦,就像街上MM、邻家小妹stuck_out_tongue_winking_eyejava

若是只是ajax的话,不能保存页面状态!一刷新就没了啊!!转瞬即逝啊!!jquery

街上的MM都走远了,童鞋别看了,找不到了!!git

若是要保存的话,结合hash#,其实很坑爹啊!es6

不少时候引入hash,致使开发复杂不说,关键是影响SEO,百度不认识 #! 啊 只有谷歌认识有毛线用啊被墙了!sobgithub

2.JPG

 

三、Pjax来了啊,喜大普奔!既能无切换、高性能加载显示html,又能跟普通url兼容,先后端开发逻辑也简单!web

就像下面的女神吉田沙世和摄影模特啊!关键是你还能抱回家,轻松hold住,各类调戏啊!卧槽。。说漏嘴了。。咳说正事!

3.jpg

4.jpg

 

 

说完了视觉上的通感感觉,咱们再看一眼开发的区别,是否是开发很麻烦啊 !!!上代码:

 

MO.go('.ctn a', '#ttt')

而后呢? 

木有了啊!只要后台再根据请求头区分下是不是pjax来返回片断html代码就能够了!

浏览器不支持pjax怎么办? 自动将极为普通http啊!!不用担忧的!

艾玛、这么happy!真幸福!

简直就是修炼玉女心经的节奏啊! 耶,操练起来!

 

 

玉女心经使用指南:

 

安装:

  1. 首先须要jQuery这个基础库~其实能够用纯js写这个pjax类库的,可是,我懒。。。
  2. 引入编译es5后到dist目录下的 mo.pjax.es5.js 脚本文件到html文件,若是使用es6,请import并配置编译
src="./dist/mo.pjax.es5.js"

能够去github上下载: https://github.com/xunuoi/MO.Pjax

 

 

用法:

 

Api Params Desc 参数注释:

 

_fetch :   是否请求网络,好比此次pjax的url参数是/about ,若是_fetch为false,那么不发送http 请求或读取缓存,只执行回调。

多用在复杂web/app设计中,好比当前内容已存在于html中,不想更新和获取.

* MO.state默认值是false,由于只是从新定义本页面状态,不须要更新已有数据和HTML 

* MO.touch中默认值是true,由于要从http或缓存中 更新数据、html

 

_fire:是否马上触发onpopfn ,马上执行回调函数。false表示popstate 事件触发后才执行

* MO.state中默认值是false, 只有popstate事件触发后才执行

* MO.go中调用了MO.state,并传参_fire值为false.

* MO.define中调用了MO.state,并传参_fire值为true.

 

 

配置:

调教一下,再美的女神也不是天生就符合你的口味,来这定制下啊!

MO.config({
    'type': 'POST', // this can be used for you back-end ,to detect if it is a pjax request 'pjaxHeader': { 'X-Http-Pjax': 'Pjax' } })

 

详细配置和注解:

{
    'type': 'POST',// post is default http请求方式 // if cache data, 是否缓存 'cache': true, // 'cacheExpires': 10000, // 0 means always avaliable, default none 缓存时间 // if store data in localStorage , default true 'storage': true, //是否启用localStorage //若是storageExpires设置为0或false,永不过时 'storageExpires': 43200000, // 12 hours ,default 12 // the res data type, default html 'dataType': 'html', //返回数据类型,默认html // you can set your own header ,just use `pjaxHeader` opts, // which you can detect if it is an pjax request in back-end // 你能够本身定义请求头,方便后端判断是不是pjax请求,若是是pjax, 返回部分html, fragment 'pjaxHeader': { 'Http-Request-Pjax': 'Fragment' }, // you can set the fn which will triggered before MO.touch and popstate event happened // 触发pjax操做前和 出现popstate的事件时的事件函数, 参数是state,包含url、title等信息 before (state) { ... } //默认无 // you can set the beforeSend fn , before ajax request send. // jquery的ajax方法调用,请求前设置请求头,能够覆盖 beforeSend (req){ let ph = this['pjaxHeader'] for (let h in ph ){ let v = ph[h] req.setRequestHeader(h, v) } } }

 

 

Api说明:

看看美女哪里长得最漂亮啊heart_eyesheart_eyes

 

1、MO.go 最简单!

MO.go(aSelector, ctnSelector, onSuccess)

这个是最简单和经常使用的api, 只须要go一下,传入2个参数便可,一个是点击后触发pjax的元素选择器,通常是a,第二个是更新返回内容的html 。第三个是回调函数,可选。

 

 

MO.go添加处理错误的函数,好比出现网络请求错误,好比404,会在此处捕获

MO.go('.ctn a', '#ttt', function onSuccess(res, $aEle){ console.log(res, $aEle) }, function onError(err, $aEle){ console.log(err, $aEle) })

 

2、MO.define 不经常使用

定义当前页面的state状态,不经常使用

MO.define(ctn, htmlData)

 

 

3、MO.state 适合复杂开发

* MO.state和MO.go二者常常配合使用,比较灵活

详细定义当前页面state状态,以及是否请求次url, 和是否马上触发onpopFn_fire

 

MO.state(url, title, onpopFn, _data=null, _fetch=false, _fire=false)

 

4、MO.go 复杂开发,很好用啊!!!

作复杂交互和逻辑时,比较经常使用

* 更强大和灵活的使用pjax, 能够定义 pjax的操做的url、回调、是否发起此url的网络请求等,一样能够添加fail的错误处理函数

 

MO.touch(apiUrl, title, onpopFn, _fetch=true)

 

给touch添加fail处理网络请求错误,添加方式以下

MO.touch(apiUrl, title, onpopFn, _fetch=true)
.fail(function(err) { console.log('There is an error ', err) }) 

 

 

 

服务端处理:

服务端只须要判断是普通请求(完整html)仍是pjax请求(fragment html)

能够经过MO.config({'pjaxHeader': {xxx: yyy}})来设置请求头,或者修改type为POST\GET等,只要让服务端能判断便可!

 

 

说明:

  • 经过MO.touch和MO.state,能够作很是复杂的pjax 应用,自定义事件\UI等
  • 若是要简单使用,就是直接 MO.go(), 传入你想要pjax的a元素的selector便可
  • 配合启用cache/localStorage(默认都启用), 给用户更好操做体验,减小等待、卡顿

 

 

 

 

本地存储:store/removeStore

原来还有这么个福利!!!

能够在引入MO.Pjax的任何页面,来store数据,当其余页面pjax到此页面的时候,数据直接从storage获取就能够啦!这个在作多重请求方式的web开发时,常常用到哦!

 

  • 提供本地存储和自动过时机制,
  • 过时时间经过MO.config({'storageExpires': xxx})来设定
  • 自动建立一个item来跟踪这条数据的时间:  { k+'createdAt': (new Date).getTime() },

 

Store的Api

 


MO.store(k, v) MO.removeStore(k, v)

 

 

 

 

MO.pjax 使用 MO.go 举例

女神跳个舞吧!!

html代码



<div class="ctn"> <h3>Test Mo.pjaxh3> <p> <a href="/about.html">Abouta> <a href="/toxic.html">Toxica> p> div> <div id="ttt" style="margin-top: 30px;"> <p>This is index htmlp> div> ------------------------------------------------------------------  <div>This is about htmldiv> ------------------------------------------------------------------  <div>This is toxic htmldiv> 

 

JS 代码

MO.go('.ctn a', '#ttt')

 

 

 

So easy! 搞定收工!

就似这么简单!就似这么任性!

我娘不再用担忧我无刷新更新页面内容了!Pjax大法好!

赶忙把pjax女神抱回家!!!heart_eyessmile

 

http://karat.cc/article/5655bcdce6fecb6c65eded27