pjax使用过程遇到的问题
文章目录
记录自己在使用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>
实际上其他变量(比如表单令牌)也可以这样传递.