Pjax
Pjax介绍:
现在很多网站( facebook, twitter)都支持这样的一种浏览方式, 当你点击一个站内的链接的时候, 不是做页面跳转, 而是只是站内页面刷新。 这样的用户体验, 比起整个页面都闪一下来说, 好很多。 其中有一个很重要的组成部分, 这些网站的ajax刷新是支持浏览器历史的, 刷新页面的同时, 浏览器地址栏位上面的地址也是会更改, 用浏览器的回退功能也能够回退到上一个页面。 那么如果我们想要实现这样的功能, 我们如何做呢? 我发现pjax提供了一个脚本支持这样的功能。 pjax项目地址在 https:// github.com/defunkt/jque ry-pjax 。 实际的效果见: http://pjax.heroku.com/ 没有勾选pjax的时候, 点击链接是跳转的。 勾选了之后, 链接都是变成了ajax刷新。
Pjax优点:
- 用户体验提升。
页面跳转的时候人眼需要对整个页面作重新识别, 刷新部分页面的时候, 只需要重新识别其中一块区域。自从我在自己的网站 GuruDigger 上面采用了pjax技术后, 不由觉得访问其他只有页面跳转的网站难受了许多。 同时, 由于刷新部分页面的时候提供了一个loading的提示, 以及在刷新的时候旧页面还是显示在浏览器中, 用户能够容忍更长的页面加载时间。 - 极大地减少带宽消耗和服务器消耗。
由于只是刷新部分页面, 大部分的请求(css/js)都不会重新获取, 网站带有用户登录信息的外框部分都不需要重新生成了。 虽然我没有具体统计这部分的消耗, 我估计至少有40%以上的请求, 30%以上的服务器消耗被节省了。
下面是Laravel框架中使用例子:
Pjax 下载:
defunkt/jquery-pjaxgithub.com前端配置:
新建一个 pjax.js,代码如下:
//定义加载区域
$(document).pjax('a','#pjax-container');
//定义pjax有效时间,超过这个时间会整页刷新
$.pjax.defaults.timeout = 1200;
//显示加载动画
$(document).on('pjax:click', function() {
$("#loading").show();
});
//隐藏加载动画
$(document).on('pjax:end', function() {
$("#loading").hide();
});
新建一个 pjax.css,用来定义一下我们加载的动画样式
#loading {
background-color: rgba(238, 238, 238, 0.6);
display: none;
position: absolute;
left: 0;
top: 0;
right: 0;
z-index: 2000;
bottom: 0;
padding-top: 10%;
}
#loading .spinner {
margin: 100px auto;
width: 50px;
height: 60px;
text-align: center;
font-size: 10px;
}
#loading .spinner > div {
background-color: rgba(0, 0, 0, 0.2);
height: 100%;
width: 6px;
display: inline-block;
-webkit-animation: stretchdelay 1.2s infinite ease-in-out;
animation: stretchdelay 1.2s infinite ease-in-out;
}
#loading .spinner .rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
#loading .spinner .rect3 {
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
#loading .spinner .rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
#loading .spinner .rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
@-webkit-keyframes stretchdelay {
0%,
40%,
100% {
-webkit-transform: scaleY(0.4);
}
20% {
-webkit-transform: scaleY(1);
}
}
@keyframes stretchdelay {
0%,
40%,
100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1);
-webkit-transform: scaleY(1);
}
}
修改 Laravel框架根目录下的 webpack.mix.js
文件,添加以下代码用于复制 plugin
目录
.mix.copyDirectory('resources/plugin', 'public/plugin')
缓存处理
js文件当加载完后,下次不会重新加载。这在使用 vue.js 时会造成第二次请求页面不效果。解决方法如下:
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "{{ asset('js/article.js') }}?ver="+Math.random();
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
把这段代码放在 pjax 容器内,对 .js 文件设置了随机后缀,就可以让页面每次请求都进行加载了。
Laravel配置
需要安装
spatie/laravel-pjaxgithub.com用于实现后台处理
$ composer require spatie/laravel-pjax
在 app/Http/Kernel.php
文件添加
protected $middleware = [
...
SpatiePjaxMiddlewareFilterIfPjax::class,
];
在项目中使用:
主模板中引入文件
<script src="https://cdn.bootcss.com/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>
<script src="{{asset('plugin/pjax/pjax.js')}}"></script>
<link rel="stylesheet" href="{{asset('plugin/pjax/pjax.css')}}">
定义 pjax加载区域
<div class="main-content container-fluid" id="pjax-container">
<!--pjax加载动画-->
<div id="loading">
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
<!--pjax加载动画 结束-->
<div id="app">
@yield('content')
</div>
</div>
Pjax 异步加载数据后会替换 id="pjax-container" 的div区域。
附件:
jquery-pjax中文文档 - BSifybsify.admui.com