第一次看到pjax是在handsome主题的设置中,这种网站无刷新的感觉让我很是舒服,于是这段时间就去折腾了一会jquery-pjax,折腾后的网站地址: http://hehuoren.no0a.cn/ 。
下面是pjax中文文档中的的一个介绍:
pjax = pushState + ajax
pjax是一个jQuery插件,它通过ajax和pushState技术提供了极速的(无刷新ajax加载)浏览体验,并且保持了真实的地址、网页标题,浏览器的后退(前进)按钮也可以正常使用。pjax的工作原理是通过ajax从服务器端获取HTML,在页面中用获取到的HTML替换指定容器元素中的内容。然后使用pushState技术更新浏览器地址栏中的当前地址。以下两点原因决定了pjax会有更快的浏览体验:
不存在页面资源(js/css)的重复加载和应用;如果服务器端配置了pjax,它可以只渲染页面局部内容,从而避免服务器渲染完整布局的额外开销。
个人对pjax的理解是将其他页面中指定的区域渲染到当前页面指定的区域,这样可以避免加载重复文件,它和ajax一样不会刷新当前页面,但是pjax可以更改浏览器地址栏的地址。
简单的实例
首先引入jquery和pjax的js文件:
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/jquery.pjax/2.0.1/jquery.pjax.min.js"></script>
在需要设为容器的标签外嵌套一个div
标签,然后为这个div标签设置一个id
,这里以content
为例。同样在其他页面中做这样的操作:
<!-- 首页内容 -->
<body>
<ul>
<li><a href="other.html">其他页面</li>
</ul>
<!-- pjax容器 -->
<div id="content">
<!-- 主体内容 -->
<div>
<p>首页</p>
</div>
</div>
</body>
<!-- 其他页面 -->
<body>
<ul>
<li><a href="index.html">首页</li>
</ul>
<!-- pjax容器 -->
<div id="content">
<!-- 主体内容 -->
<div>
<p>其他页面</p>
</div>
</div>
</body>
为使用pjax的链接添加data-pjax属性,这样只有被添加属性的超链接才会实现生效:
<a data-pjax href="other.html">
<a data-pjax href="index.html">
然后将js文件添加到每个页面中:
$(function() {
$(document).pjax('a[data-pjax]', '#content', {fragment: '#content',timeout: 8000, type: 'GET'});
})
最后如果网站内容较多或者服务器较慢,可以为pjax添加加载动画以提升用户体验(加载动画在遇到的问题中有写),这样一个简单的实例就做好了。更多其他关于jquery-pjax的使用可以查看中文文档:jquery-pjax中文文档
遇到的问题
pjax未生效
第一次使用时pjax没有生效,控制台报错,发现是没有引入jquery,由于现在使用的pjax是依赖jquery的,所以需要先引入jquery。但是引入之后还是没有生效,控制台也没有报错,翻了一会文档发现pjax只能在服务器环境下使用,于是将文件移到本地服务器环境下,终于pjax生效了。
pjax加载区域
折腾网址使用的是bootstrap
框架,用了pjax后加载的内容部分样式丢失,打开控制台查看网网页源码,发现pjax加载的区域是容器里面的内容,这个区域不包括容器本身,例如:
<div id="content" class="container">
<div id="demo">
...
</div>
</div>
如果直接将引用了container
类的div
标签设置为容器,pjax加载时只会从id
为demo
的div
标签开始加载,所以一般使用pjax时可以在原来需要加载的区域外面嵌套一个div
,修改后的代码:
<div id="content">
<div class="container">
<div id="demo">
...
</div>
</div>
</div>
链接作用范围
pjax一般在超链接a
标签中使用,但是加载的区域中还会有一些不需要使用到pjax的a
标签,这时可以对需要使用pjax的a
标签设置data-pjax
属性,然后在js中将a[data-pjax]
设为选择器,这样pjax将只会作用在添加了data-pjax
属性的a
标签上。
js文件
一般情况下网站都会提前将所有js文件引入到页面中,而pjax只会用来加载部分网页内容,但是这次折腾的网站几乎每一个页面都会有一个独立的js文件,本来准备将所有js文件合并到一个js文件中,但是感觉工程量比较大就放弃了,于是将单独的js文件放入容器中引入。
这种做法虽然可行,但是head
标签中会添加上很多js文件,于是想到了在每次加载其他页面内容前将head
标签中非当前页面js文件全都去除:
$(document).on('pjax:send', function() {
$('head>script[src!="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"]').remove();
});
这样做就不会将很多js文件引入到当前页面中了。
加载动画
有些网页内容较多或者服务器比较慢,这时就可以使用加载动画提升用户体验。加载动画的使用方法是在pjax开始时打开加载动画,在pjax结束时关闭加载动画。
刚开始使用的是一个忘了在哪看到的加载动画,后来看到了保罗的小窝的加载动画,觉得这种效果也挺不错的,便选择了后者,但是由于没有在网站里面翻到代码,只能自己简单地写了个动画。最后附上这两种加载动画代码:
不知名加载动画效果:
html:
<div class="loading" style="display: none;"> <div id="loader"></div></div>
css:
.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);}}
js:
$(function() {
$(document).pjax('a[data-pjax]', '#content', {fragment: '#content',timeout: 8000, type: 'GET'});
$(document).on('pjax:send', function() {
$(".loading").css("display", "block");
});
$(document).on('pjax:complete', function() {
$(".loading").css("display", "none");
});
})
上下渐隐渐现加载动画效果
css:
#content {
transition: all 500ms;
}
.pjax-active{
animation-direction:alternate;
transform: translateY(100px);
opacity: 0;
}
js:
$(function() {
$(document).pjax('a[data-pjax]', '#content', {fragment: '#content',timeout: 8000, type: 'GET'});
$(document).on('pjax:send', function() {
$("#content").addClass("pjax-active");
});
$(document).on('pjax:complete', function() {
$("#content").removeClass("pjax-active");
});
})
上面就是自己开始使用pjax的总结,当然pjax的功能可不止这么多,更多的使用方法需要以后慢慢探索。好了,这次就到这里吧。
6 条评论
想想你的文章写的特别好www.jiwenlaw.com
不错不错,我喜欢看 www.jiwenlaw.com
为什么我的pajx评论不会生效
打错了pjax
如果html是直接由后端生成,可以用过协议头判断是否pjax来控制是否返回局部html
后端需要另外的配置吗 判断请求是否是pjax啥的