pjax使用小结
简介
虽然传统的ajax方式可以异步无刷新改变页面内容,但无法改变页面URL,因此有种方案是在内容发生改变后通过改变URL的hash的方式获得更好的可访问性(如https://liyu365.github.io/BG-UI/tpl/#page/desktop.html),但是hash的方式有时候不能很好的处理浏览器的前进、后退,而且常规代码要切换到这种方式还要做不少额外的处理。而pjax的出现就是为了解决这些问题,简单的说就是对ajax的加强。
pjax结合pushState和ajax技术, 不需要重新加载整个页面就能从服务器加载Html到你当前页面,这个ajax请求会有永久链接、title并支持浏览器的回退/前进按钮。
pjax项目地址在 https://github.com/defunkt/jquery-pjax 。 实际的效果见:https://pjax.herokuapp.com/ 没有勾选pjax的时候点击链接是跳转的, 勾选了之后链接都是变成了ajax刷新(实际效果如下图的请求内容对比)。
优点:
- 减轻服务端压力
按需请求,每次只需加载页面的部分内容,而不用重复加载一些公共的资源文件和不变的页面结构,大大减小了数据请求量,以减轻对服务器的带宽和性能压力,还大大提升了页面的加载速度。
- 优化页面跳转体验
常规页面跳转需要重新加载画面上的内容,会有明显的闪烁,而且往往和跳转前的页面没有连贯性,用户体验不是很好。如果再遇上页面比较庞大、网速又不是很好的情况,用户体验就更加雪上加霜了。使用pjax后,由于只刷新部分页面,切换效果更加流畅,而且可以定制过度动画,在等待页面加载的时候体验就比较舒服了。
缺点:
- 不支持一些低版本的浏览器(如IE系列)
pjax使用了pushState来改变地址栏的url,这是html5中history的新特性,在某些旧版浏览器中可能不支持。不过pjax会进行判断,功能不适用的时候会执行默认的页面跳转操作。
- 使服务端处理变得复杂
要做到普通请求返回完整页面,而pjax请求只返回部分页面,服务端就需要做一些特殊处理,当然这对于设计良好的后端框架来说,添加一些统一处理还是比较容易的,自然也没太大问题。另外,即使后台不做处理,设置pjax的fragment参数来达到同样的效果。
综合来看,pajx的优点很强势,缺点也几乎可以忽略,还是非常值得推荐的,尤其是类似博客这种大部分情况下只有主体内容变化的网站。关键它使用简单、学习成本小,即时全站只有极个别页面能用得到,尝试下没什么损失。pjax的github主页介绍的已经很详细了,想了解更多可以看下源码。
用法
- 引入jquery和jquery.pjax.js
- 注册事件
/**
* 方式一 按钮父节点监听事件
*
* @param selector 触发点击事件的按钮
* @param container 展示刷新内容的容器,也就是会被替换的部分
* @param options 参数
*/
$(document).pjax(selector, [container], options);
// 方式二 直接对按钮监听,可以不用指定容器,使用按钮的data-pjax属性值查找容器
$("a[data-pjax]").pjax();
// 方式三 常规的点击事件监听方式
$(document).on('click', 'a', $.pjax.click);
$(document).on('click', 'a', function(event) {
var container = $(this).closest('[data-pjax-container]');
$.pjax.click(event, container);
});
// 下列是源码中介绍的其他用法,由于本人暂时没有那些需求暂时没深究,有兴趣的各位自己试试看哈
// 表单提交
$(document).on('submit', 'form', function(event) {
var container = $(this).closest('[data-pjax-container]');
$.pjax.submit(event, container);
});
// 加载内容到指定容器
$.pjax({ url: this.href, container: '#main' });
// 重新当前页面容器的内容
$.pjax.reload('#container');
options默认参数说明
参数名 | 默认值 | 说明 |
---|---|---|
timeout | 650 | ajax 超时时间(单位ms),超时后会执行默认的页面跳转,所以超时时间不应过短,不过一般不需要设置 |
push | true | 使用window.history.pushState改变地址栏url(会添加新的历史记录) |
replace | false | 使用window.history.replaceState改变地址栏url(不会添加历史记录) |
maxCacheLength | 20 | 缓存的历史页面个数(pjax加载新页面前会把原页面的内容缓存起来,缓存加载后其中的脚本会再次执行) |
version | 是一个函数,返回当前页面的pjax-version,即页面中<meta http-equiv="x-pjax-version">标签内容。使用response.setHeader("X-PJAX-Version", "") 设置与当前页面不同的版本号,可强制页面跳转而不是局部刷新。 |
|
scrollTo | 0 | 页面加载后垂直滚动距离(与原页面保持一致可使过度效果更平滑) |
type | "GET" | ajax的参数,http请求方式 |
dataType | "html" | ajax的参数,响应内容的Content-Type |
container | 用于查找容器的CSS选择器,[container]参数没有指定时使用 | |
url | link.href | 要跳转的连接,默认a标签的href属性 |
target | link | pjax事件参数e的relatedTarget属性,默认为点击的a标签 |
fragment | 使用响应内容的指定部分(css选择器)填充页面,服务端不进行处理导致全页面请求的时候需要使用该参数,简单的说就是对请求到的页面做截取 |
pjax失效情况除了上述参数外,ajax的一些参数也是可以设置在这里的,不过一般没什么必要。// ajax 最终参数: options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options);
会有一些情况导致pjax失效,下面结合源码分析下(省略部分无关代码)
function handleClick(event, container, options) {
... // 1. 点击事件的事件源不是a标签。使用a标签可以做到对旧版本浏览器的兼容,所以不建议使用其他标签注册事件
if (link.tagName.toUpperCase() !== 'A')
throw "$.fn.pjax or $.pjax.click requires an anchor element" // 2. 使用鼠标滚轮点击(新标签页打开)
// 点击超链接的同时按下Shift、Ctrl、Alt和Meta(在Windows键盘中是Windows键,在苹果机中是Cmd键)
// 作用分别代表新窗口打开、新标签打开(不切换标签)、下载、新标签打开(切换标签)
if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
return // 3. 跨域(网络通讯协议,域名不一致)
if (location.protocol !== link.protocol || location.hostname !== link.hostname)
return // 4. 当前页面的锚点定位
if (link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location))
return // 5. 已经阻止元素发生默认的行为(url跳转)
if (event.isDefaultPrevented())
return ... var clickEvent = $.Event('pjax:click')
$(link).trigger(clickEvent, [opts]) // 6. pjax:click事件回调中已经阻止元素发生默认的行为(url跳转)
if (!clickEvent.isDefaultPrevented()) {
pjax(opts)
event.preventDefault()// 阻止url跳转
$(link).trigger('pjax:clicked', [opts])
}
}
除了上述情况之外,还有下列几种情况:
- ajax请求失败,或者timeout后请求被中止
- 当前页面X-PJAX-Version和请求的新页面版本不一致
- 请求得到完整的页面(包含html标签)却没设置fragment参数
事件
1. 点击链接后触发的一系列事件, 除了pjax:click 和 pjax:clicked的事件源是点击的按钮,其他事件的事件源都是要替换内容的容器。可以在pjax:start事件触发时开始过度动画,在pjax:end事件触发时结束过度动画。
事件名 | 支持取消 | 参数 | 说明 |
---|---|---|---|
pjax:click | ✔ |
options | 点击按钮时触发。可调用e.preventDefault(); 取消pjax |
pjax:beforeSend | ✔ |
xhr, options | ajax执行beforeSend 函数时触发,可在回调函数中设置额外的请求头参数。可调用e.preventDefault(); 取消pjax |
pjax:start | xhr, options | pjax开始(与服务器连接建立后触发) | |
pjax:send | xhr, options | pjax:start之后触发 | |
pjax:clicked | options | ajax请求开始后触发 | |
pjax:beforeReplace | contents, options | ajax请求成功,内容替换渲染前触发 | |
pjax:success | data, status, xhr, options | 内容替换成功后触发 | |
pjax:timeout | ✔ |
xhr, options | ajax请求超时后触发。可调用e.preventDefault(); 继续等待ajax请求结束 |
pjax:error | ✔ |
xhr, textStatus, error, options | ajax请求失败后触发。默认失败后会跳转url,如要阻止跳转可调用 e.preventDefault(); |
pjax:complete | xhr, textStatus, options | ajax请求结束后触发,不管成功还是失败 | |
pjax:end | xhr, options | pjax所有事件结束后触发 |
注意:pjax:beforeReplace事件前pjax会调用extractContainer函数处理页面内容,即script[src]形式引入的js脚本不会被重复加载,有必要可以改下源码。
2. 浏览器前进/后退导航时触发的事件(暂时没做过多研究)
事件名 | 参数 | 说明 |
---|---|---|
pjax:popstate | 页面导航方向: 'forward'/'back'(前进/后退) | |
pjax:start | null, options | pjax开始 |
pjax:beforeReplace | contents, options | 内容替换渲染前触发,如果缓存了要导航页面的内容则使用缓存,否则使用pjax加载 |
pjax:end | null, options | pjax结束 |
插件伴侣——NProgress
比较漂亮的一款进度条插件,用法十分简单,很适合做pjax的过度动画,详细用法在该项目github上有介绍
- 示例:
$(document).on('pjax:start', NProgress.start).on('pjax:end', NProgress.done);
示例连接:https://iathanasy.github.io/html/pjax/
原文链接: https://www.cnblogs.com/telwanggs/p/7136716.html
pjax使用小结的更多相关文章
- jQuery+pjax简单示例汇总
pjax 是一个jQuery插件,它使用 ajax 和 pushState 来实现快速的浏览体验,包括真正的固定链接,页面标题和工作返回按钮. ajax缺点是破坏了浏览器的前进后退,因为ajax的请求 ...
- 从零开始编写自己的C#框架(26)——小结
一直想写个总结,不过实在太忙了,所以一直拖啊拖啊,拖到现在,不过也好,有了这段时间的沉淀,发现自己又有了小小的进步.哈哈...... 原想框架开发的相关开发步骤.文档.代码.功能.部署等都简单的讲过了 ...
- Python自然语言处理工具小结
Python自然语言处理工具小结 作者:白宁超 2016年11月21日21:45:26 目录 [Python NLP]干货!详述Python NLTK下如何使用stanford NLP工具包(1) [ ...
- java单向加密算法小结(2)--MD5哈希算法
上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇要说的MD5,其实也不算是加密算法,而是一种哈希算法,即将目标文本转化为固定长度,不可逆的字符 ...
- iOS--->微信支付小结
iOS--->微信支付小结 说起支付,除了支付宝支付之外,微信支付也是我们三方支付中最重要的方式之一,承接上面总结的支付宝,接下来把微信支付也总结了一下 ***那么首先还是由公司去创建并申请使用 ...
- iOS 之UITextFiled/UITextView小结
一:编辑被键盘遮挡的问题 参考自:http://blog.csdn.net/windkisshao/article/details/21398521 1.自定方法 ,用于移动视图 -(void)mov ...
- K近邻法(KNN)原理小结
K近邻法(k-nearst neighbors,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用.比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出 ...
- scikit-learn随机森林调参小结
在Bagging与随机森林算法原理小结中,我们对随机森林(Random Forest, 以下简称RF)的原理做了总结.本文就从实践的角度对RF做一个总结.重点讲述scikit-learn中RF的调参注 ...
- Bagging与随机森林算法原理小结
在集成学习原理小结中,我们讲到了集成学习有两个流派,一个是boosting派系,它的特点是各个弱学习器之间有依赖关系.另一种是bagging流派,它的特点是各个弱学习器之间没有依赖关系,可以并行拟合. ...
随机推荐
- http://blog.csdn.net/pizi0475/article/details/48286579 -------------(Collada 快速入门)
http://blog.csdn.net/zhouhangjay/article/details/8469085 说明:Collada的文件格式,中文版的很少,在csdn上看到了一个Sleepy的,感 ...
- VM虚拟机NAT链接外网
1.vi /etc/sysconfig/networkNETWORKING=yesHOSTNAME=localhost.localdomainGATEWAY=192.168.110.2 2.vi /e ...
- Idea 创建maven web项目(手工创建)
参考链接:https://www.cnblogs.com/justuntil/p/7511787.html 话不多说,直接上图: 1.创建maven项目 创建项目完成,项目结构如下: 2.项目部署配置 ...
- Problem 34
Problem 34 https://projecteuler.net/problem=34 145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 1 ...
- svn 使用TortoiseSVN server搭建本地SVN服务器
使用TortoiseSVN server搭建本地SVN服务器
- python BeautiulSoup
==============================================查找网页中<a>标签中的链接from bs4 import BeautifulSoup with ...
- BZOJ 1631 Usaco 2007 Feb. Cow Party
[题解] 最短路裸题.. 本题要求出每个点到终点走最短路来回的距离,因此我们先跑一遍最短路得出每个点到终点的最短距离,然后把边反向再跑一遍最短路,两次结果之和即是答案. #include<cst ...
- MYSQL 字符集 MYSQL 源码
http://blog.csdn.net/maray/article/details/46504621
- UNIX环境高级编程之第3章:文件I/O
3.1 引言 文件I/O函数:打开文件,读文件,写文件 经常使用到五个函数:open, read, write, lseek, close. 本章描写叙述的函数都是:不带缓冲的I/O(unbuffer ...
- 卸载完百度影音以后天气助手还在,而且总是自己主动打开ie浏览器,解决方式
今天暴风影音不好用了.我就安装了百度影音,还有意外发现.相同的视频,用百度影音看不清楚,然后我就直接卸载了.结果卸掉以天气小助手还是在,而且总弹白色小框框,各种广告.最忍不了的是还自己主动打开ie浏览 ...