pjax 笔记

PJAX的基本思路是,用户点击一个连接,经过ajax更新页面变化的部分,而后使用HTML5的pushState修改浏览器的URL地址,这样有效地避免了整个页面的从新加载。若是浏览器不支持history的两个新API或者JS被禁用了,那这个连接就只能跳转并从新刷新整个页面了。和传统的ajax设计稍微不一样,ajax一般是从后台获取JSON数据,而后由前端解析渲染,而PJAX请求的是一个在服务器上生成好的HTML碎片.css

客户端向服务器发送一个普通的请求(1),其实也就是点击了一个连接,服务器会相应这个请求(2),返回一个html文档。客户端向服务器发送一个有PJAX标志的请求(3),此时服务器只返回一个html碎片(4)。可是这两次请求都让客户端的URL变化了,但愿上面的说明可让你明白了PAJX和AJAX的区别了。html

 

用法

  1. 引入jquery和jquery.pjax.js
  2. 注册事件
    /**
     * 方式一 按钮父节点监听事件
     *
     * @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失效状况


会有一些状况致使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])
    }
}

 

除了上述状况以外,还有下列几种状况:jquery

  • ajax请求失败,或者timeout后请求被停止
  • 当前页面X-PJAX-Version和请求的新页面版本不一致
  • 请求获得完整的页面(包含html标签)却没设置fragment参数

 
实际操做中出现问题: 
pajx在浏览器回退和前进是无任何问题的。但若是你进行刷新或F5操做。那么加载出来的页面仅仅为地址栏后台请求出来的页面:好比,若是你的菜单栏项是经过pjax(这里请求的页面dom为 a/list.html)加载对应的内容到指定div(这里假设为div1)。那么若是进行了刷新或F5操做后页面出现的仅仅为 a/list.html页面的布局和信息。如何解决? 
pajx在提交的头信息中包括了 x-pjax: truegit

  • 1.服务器端判断是否为x-pjax请求github

    服务器后台可经过该字段来判断是否为x-pjax请求。或者本身定义好参数传到后台来区分是不是x-pjax的请求。ajax

  • 2.若是不为x-pjax请求则转发到首页地址跨域

    若是你菜单项的首页为index.html 则转发到该页面。那么在刷新后就可以跳转到首页。包含了菜单项等。浏览器

@Controller
public class TestController {
    
    @RequestMapping("/")
    public String index(){
        return "index";
    }
    
    @RequestMapping("/data")
    public String test(HttpServletRequest request){
        boolean b = Boolean.valueOf(request.getHeader("x-pjax"));
        if(b){
            
        }else{
            return "redirect:/";
        }
        return "test";
    }

}
相关文章
相关标签/搜索