记录自己在使用pjax过程遇到的问题.

PJAX 就是 web的异步局部更新.我博客整体都用了pjax来局部更新.(实际上我更新的是整个body)

好处就是只有第一次打开页面才需要请求js/css 后续页面不需要跳转, 后续页面也不需要请求js/css.并且保持浏览器的前进后退功能可以用.

 

 

PJAX简单理解

 

在我看来,PJAX实际表现就是.

 

1,当用户点击链接后,不直接跳转将请求变成ajax异步请求.

2,当用户ajax请求在指定时间内获取成功了网页,那么将网页内容更新到某个dom内,(并对地址栏做出调整). 如果在指定时间没有获取网页内容那么就执行跳转.

 

 

问题点

 

1,超时问题

 

默认pjax请求好像只有0.65秒左右,如果请求未获得网页返回,那么执行跳转.

 

$(document).pjax('a', 'body', { fragment: 'body',timeout: 8000  });

 

这里就是改成8秒.

我这里参数

第一个是 "a"  : 这个就是点击事务委托的元素.  (可以指定某个div内的a)

第二个是"body" : 用来寄存新页面内容的dom父容器. (也可以指定某个div,不一定要放body)

第三个就是可选参数了,官方文档有很多.  timeout就是超时值,.fragment好像应用css的容器. 一般这个和第二个是一样的.

 

 

2,表单令牌失效问题.

 

最开始,我是所有页面都输出一个表单令牌.但是遇到两个问题.

 

一, 当提交某个表单后,表单令牌失效,除非刷新页面.

二,当用户执行浏览器后退的时候,上一页的令牌早就失效了.

 

 

我这里的方案是

一,首页面(非pjax请求的),输出表单令牌.

二,其他页面是pjax的,不输出表单令牌,也就是令牌没有被更新.

三,当用户异步提交表单,无论成功或者失败,都返回一个新的表单令牌.(原来的因为被校验了所以失效了.)

 

这样极大的减少了表单令牌校验.用户提交后,不需要刷新页面, 提交表单的同时也更新了表单令牌.

 

 

3,表单pjax请求

也就是我博客搜索功能. 搜索也是用的pjax,不需要跳转.

 

要求用户输入长度限制2-10个字符.如果是,用pjax接管提交.否者给出提示并停止提交.

    $(document).pjax('a', 'body', { fragment: 'body',timeout: 8000  });

    //监听表单提交.
    $(document).on('submit', '#morphsearch-form', function (event) {

      let keyword = $('#search-keyword').val();    //获取搜索编辑框的内容

      //长度判断
      if (keyword.length < 2 || keyword.length > 10 ){
        alert("搜索长度应道在2-10个字符之间");
        return false;            //不提交,直接返回
      }else{
         
         //pjax接管提交事件.
        $.pjax.submit(event, 'body', {
          fragment:'body', timeout:8000
        });
      }

    });

 

4,网页title标题更新

 

pjax是局部刷新,虽然他将浏览器历史记录变化了.但是他没有更新网页的标题.

这个非常简单.

只需要在返回的页面,单独添加一个title标签,那么会自动更新网页标题.

 

<title>Y.A.K.E -- 赛博朋克2077 修改器</title>

同理也可以添加网页描述,网页关键词.

 

5,JS事件处理

我之前尝试的时候发现pjax网页中的js可能不一定有效果.

所以我事件都是统一处理.

 

我博客处理方案是:

定义一个全局安装函数. setup()

 

然后,当pjax完成后自动调用.

    $(document).on('pjax:complete', function () {
      setup();
    });
  };

这样每次pjax请求后,就会执行这个setup.

当然网页首次打开不是pjax的,

需要单独执行一次setup();

 

6,重复初始化的问题

 

这是算我个例了.

比如我任意博文下面有个编辑器,编辑器是需要初始化的.

当我们pjax请求后.如果再执行初始化一次就会出错.

评论中,载入更多评论按钮.如果博文一切到博文二,就会出现载入更多按钮用不了的情况,需要再setup函数中,先解绑再绑定.

    //解绑并重新注册,防止PJAX部分问题
    $('.vpage .vmore').unbind("onclick");
    //重新注册
    $('.vpage .vmore').click(function(){
       //....
    });

 

对于一些页面独有的事件处理.比如这里编辑器的初始化还有销毁.

if($('#tinydemo').length){   //只有博文详细页才有这个div
   if (tinyMCE && tinyMCE.editors.length){   //如果已经初始化了就销毁
	   tinyMCE.editors['tinydemo'].destroy();
   }
   tinymce.init({
		 //..初始化
   });;
}

 

这个都是挂在setup()中的.

 

 

记录一些我奇怪的用法

 

仅我个人使用并记录.非常规的方案.

 

1.覆盖window变量

 

我在所有页面都输出一个window变量.这个变量会被新pjax请求的网页内容覆盖.

<script>
    window.search_keyword = "";
</script>

实际上其他变量(比如表单令牌)也可以这样传递.