使用jquery-pjax实现网站无刷新总结

第一次看到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加载时只会从iddemodiv标签开始加载,所以一般使用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的功能可不止这么多,更多的使用方法需要以后慢慢探索。好了,这次就到这里吧。

jquery-pjax中文文档

地址:jquery-pjax中文文档

Last modification:May 23rd, 2019 at 11:02 am
If you think my article is useful to you, please feel free to appreciate

Leave a Comment