一点微小的工作,初步实现无刷新加载。
本教程仅在Fluid主题1.8.1版本测试通过。
一、介绍 pjax是什么?
pjax 结合 pushState 和 ajax 技术(PJAX=history.pushState+ajax), 不需要重新加载整个页面就能从服务器加载 Html 到你当前页面,这个 ajax 请求会有永久链接、title 并支持浏览器的回退/前进按钮。
简单来说pjax就是无刷新加载 ,看起来似乎很高端,但其实很多网站都已经在使用和pjax类似的技术,比如百度搜索:在搜索页更换关键词搜索,页面只是部分内容重载。
pjax的优点和好处很多,仅就个人博客而言,最直观的体验就是能够实现页面平滑切换 和音乐不间断播放 。
pjax效果演示:http://pjax.herokuapp.com ~~ 或者就在本站体验 。 ~~
pjax这般优秀,奈何本站使用的如此好看的Fluid主题竟然不支持,只好自己动手,慢慢摸索和折腾一下。
二、安装 1、版本选用 ONE.jquery-pjax TWO.Moox-pjax
第一个是需要使用jquery依赖的版本,俩版本大同小异,只是后者代码更新日期较新,在这里我选用了后者。
推荐首先阅读下官方文档 。
2、引入js 在/主题目录/layout/partial/footer.ejs
中加入
1 <script src ="https://cdn.jsdelivr.net/npm/pjax@0.2.8/pjax.js" > </script >
来引入pjax;
或者使用npm安装本地后引用
1 <script src ="./node_modules/pjax/pjax.js" > </script >
现在,我们已经安成了pjax的安装,本地预览一下,页面跳转已初见成效。但你可能会发现,标题消失、图片失效等等各项功能异常。别着急,这是由于部分js未能加载导致的,稍后会解决。
三、使用 1、功能配置 在/主题目录/layout/layout.ejs
中插入代码:
1 2 3 4 5 6 7 8 9 10 <script > var pjax = new Pjax({ selectors : [ "title" , "main" , "header" , ] }) </script >
elements选择触发器,即点击什么来触发pjax(只能用a或者form),a为链接。 selectors根据css选择器来选择更新的节点(即当触发elements时哪些内容会刷新,其余部分保持不变)
有用的pjax函数
1 2 3 4 pjax.loadUrl(); document .addEventListener('pjax:send' , function ( ) {});document .addEventListener('pjax:complete' , function ( ) {});document .addEventListener('pjax:error' , function ( ) {});
2、项目优化 2.1 Valine评论重载 在Fluid1.8.1版本中已经解决了 pjax刷新后发现评论不能加载 这个问题 ,如果使用1.8.0及以下版本 需要进行下面的操作。 在/主题目录/layout/layout.ejs
中插入代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 function LoadValine ( ) { $.getScript("https://cdn.staticfile.org/valine/1.4.14/Valine.min.js" , function ( ) { var GUEST_INFO = ['nick' ,'mail' ,'link' ]; var guest_info = '<%= theme.valine.meta %>' .split(',' ).filter(function (item ) { return GUEST_INFO.indexOf(item) > -1 }); var valine = new Valine(); valine.init({ el : "#vcomments" , guest_info : guest_info, app_id : "<%= theme.valine.appid %>" , app_key : "<%= theme.valine.appkey %>" , placeholder : "<%= theme.valine.placeholder %>" , path : <%= theme.valine.path %>, avatar: "<%= theme.valine.avatar %>" , meta : <%- JSON .stringify(theme.valine.meta || []) %>, pageSize: "<%= theme.valine.pageSize %>" , lang : "<%= theme.valine.lang %>" , highlight : <%= theme.valine.highlight %>, recordIP: <%= theme.valine.recordIP %>, serverURLs: "<%= theme.valine.serverURLs %>" }) }); };
然后进行这个函数的重载
1 2 3 document .addEventListener('pjax:complete' , function ( ) { LoadValine(); });
如果在自建页面 使用了Valine评论 ,仍需要添加//加载valine
函数,但是请将重载指令放在评论所在页面的.md文件中,避免出现评论重复加载现象。同时为了保证在该页面刷新时重载评论,需要使用pjax的load函数。 完整示例如下:
1 2 3 4 5 6 7 8 9 <script > document .addEventListener('pjax:complete' , function ( ) { LoadValine(); }); window .addEventListener('load' ,function ( ) { LoadValine(); }); </script >
然而,这样操作以后,还是会出现一些bug:在文章页评论加载完毕以后,用户跳转留言页,再返回到刚刚访问的文章页时,会出现评论重复的现象。我还在寻找修复方法,但是一般访问情景应该不会有特别大的影响。(谁会在页面之间反复横跳呢?)
2.2 懒加载修复 在/主题目录/layout/layout.ejs
中添加重载函数如下:
1 2 3 document .addEventListener('pjax:complete' , function ( ) { $.getScript("/js/lazyload.js" ); });
2.3 下滑箭头、抖动等修复 在/主题目录/layout/layout.ejs
中插入代码:
1 2 3 4 5 6 7 8 9 document .addEventListener('pjax:complete' , function ( ) { $.getScript("/js/main.js" ); $.getScript("/js/debouncer.js" ); }); window .addEventListener('load' ,function ( ) { $.getScript("/js/main.js" ); });
2.4 FancyBox重载 在/主题目录/layout/layout.ejs
中插入代码:
1 2 3 4 5 6 7 8 9 10 11 function LoadFancyBox ( ) { $('#post img:not(.no-zoom img, img[no-zoom]), img[zoom]' ).each( function ( ) { var element = document .createElement('a' ); $(element).attr('data-fancybox' , 'images' ); $(element).attr('href' , $(this ).attr('src' )); $(this ).wrap(element); } ); };
然后进行这个函数的重载
1 2 3 4 document .addEventListener('pjax:complete' ,function ( ) { LoadFancyBox(); });
bug:在关闭放大的图片后,页面会漂移。 我暂时关闭了这个功能。
2.5 修复MarkDown样式丢失 在Fluid1.8.1的更新 中,强哥加入判断以减少不必要的加载项,但加入pjax之后判断似乎失效了,那么就干脆不要判断好了(反向升级)。 将/主题目录/layout/_partial/css.ejs
中的<% if (is_post() || is_page()) { %>
判断删除即可。
2.6 加入加载动画 css如下:
1 2 3 4 5 6 7 8 .loading {display :none}.loading {height :100% ;width :100% ;position :fixed;top :0 ;left :0 ;z-index :999999 ;background-color :rgba (250 ,250 ,250 ,.9 )}.loading img {width : 280px ;height :210px ;position : relative;top : 45% ;left : 50% ;margin-left :-140px ;margin-top : -105px ;}#loader {display : block; position : relative; left : 50% ; top : 50% ; width : 150px ; height : 150px ; margin : -75px 0 0 -75px ; border-radius : 50% ; border : 3px solid transparent; border-top-color : #ff5a5a ; -webkit-animation : spin 1s linear infinite; animation : spin 1s linear infinite;}#loader :before{content: "" ; position : absolute; top : 5px ; left : 5px ; right : 5px ; bottom : 5px ; border-radius : 50% ; border : 3px solid transparent; border-top-color : #5af33f ; -webkit-animation : spin 3s linear infinite; animation : spin 3s linear infinite;}#loader :after{content: "" ; position : absolute; top : 15px ; left : 15px ; right : 15px ; bottom : 15px ; border-radius : 50% ; border : 3px solid transparent; border-top-color : #6dc9ff ; -webkit-animation : spin 2s linear infinite; animation : spin 2s linear infinite;}@-webkit-keyframes spin{0% {-webkit-transform : rotate (0deg ); -ms-transform : rotate (0deg ); transform : rotate (0deg );} 100% {-webkit-transform : rotate (360deg ); -ms-transform : rotate (360deg ); transform : rotate (360deg );}}@keyframes spin{0% {-webkit-transform : rotate (0deg ); -ms-transform : rotate (0deg ); transform : rotate (0deg );} 100% {-webkit-transform : rotate (360deg ); -ms-transform : rotate (360deg ); transform : rotate (360deg );}}
pjax载入动画:
1 2 3 4 5 6 7 8 document .addEventListener('pjax:send' , function ( ) { $(".loading" ).css("display" , "block" ); }); document .addEventListener('pjax:complete' , function ( ) { $(".loading" ).css("display" , "none" );
另外推荐一下Nprogress.js也很好看。
四、本站pjax完整代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <script > var pjax = new Pjax({ selectors : [ "title" , "main" , "header" , ] }) function LoadValine ( ) { $.getScript("https://cdn.staticfile.org/valine/1.4.14/Valine.min.js" , function ( ) { var GUEST_INFO = ['nick' ,'mail' ,'link' ]; var guest_info = '<%= theme.valine.meta %>' .split(',' ).filter(function (item ) { return GUEST_INFO.indexOf(item) > -1 }); var valine = new Valine(); valine.init({ el : "#vcomments" , guest_info : guest_info, app_id : "<%= theme.valine.appid %>" , app_key : "<%= theme.valine.appkey %>" , placeholder : "<%= theme.valine.placeholder %>" , path : <%= theme.valine.path %>, avatar: "<%= theme.valine.avatar %>" , meta : <%- JSON .stringify(theme.valine.meta || []) %>, pageSize: "<%= theme.valine.pageSize %>" , lang : "<%= theme.valine.lang %>" , highlight : <%= theme.valine.highlight %>, recordIP: <%= theme.valine.recordIP %>, serverURLs: "<%= theme.valine.serverURLs %>" }) }); }; document .addEventListener('pjax:send' , function ( ) { $(".loading" ).css("display" , "block" ); }); document .addEventListener('pjax:complete' , function ( ) { $(".loading" ).css("display" , "none" ); $.getScript("/js/lazyload.js" ); $.getScript("/js/main.js" ); $.getScript("/js/debouncer.js" ); }); window .addEventListener('load' ,function ( ) { $.getScript("/js/main.js" ); }); </script >
五、To Do List 以下功能暂时还没有修复,后期慢慢研究,也期待有大佬提供解决方案。
代码高亮和复制按钮 Valine评论重复问题 FancyBox漂移问题 Typed.js文本打字机 Toc.js文章目录 anchor锚点 其他评论系统 Editor.md编辑器
六、后记 参考文章:https://www.jianshu.com/p/557cad38e7dd https://inkss.cn/article/other/80b5f235.html 感谢:lluuiq 和 MoMik 对本站pjax实现过程中的指导和帮助。 由于个人能力实在有限,导致bug多多,还是期待Fluid官方支持pjax。