Pjax用法 & Pjax在yii2中的使用介绍 [基础教程]

作者:下班闪电去打卡 发布于:2016-09-25 浏览:3950次 收藏

Pjax简介

pjax和ajax一样都是异步请求,只不过比ajax多做了一件事情。大家看完一个等式就明白了:

pjax = pushState + ajax

pushState就是这件需要多做的事情。

Ps:提醒大家一点, 部分浏览器的低级版本不支持pjax的,如:IE7、8,具体有哪些自己去实践、百度吧,不过个人感觉身边已经很多浏览器高点的版本都已经支持了,以后广泛使用是必然的!


开始正题,举一个现实生活中经常遇到的例子,比如有一个需求: 不刷新翻页。 大家会怎么做?

相信大家第一反应就是ajax请求啊!是的,ajax可以很好的解决。我们写好js代码、后台代码,然后点击下一页触发异步请求,后台处理后响应数据,js拿到数据渲染页面,实现了翻页效果,再点击下一页又翻页了。目前为止这种效果已经是有了比较好的用户体验,但是我们可以继续提高。试想:我点击了下一页,翻页后现在我想后退,如果点击浏览器的后退按钮,那肯定是不行的,我们只能点击页面中的‘上一页’按钮。并且点击会再次触发ajax请求,如果数据缓存过期了,需要重新查询数据。这就是需要优化的地方。pjax可以解决这些问题。


pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button.


1、首先下载pjax插件https://github.com/defunkt/jquery-pjax

此插件是一个jq插件,所以要先加载jquery,这个不用多说。(如果是整个下载,里面只有jquery.pjax.js是用得到的)


2、引用、应用:

list.php视图文件

<div id="pjax-container">
    <div id="pjax-content">    
        翻页数据
        .......
        .......
        .......
        .......                
    </div><!-- 闭合pjax-content -->
</div><!-- 闭合pjax-container -->


<script src="/assets/f2f7c559/jquery.js"></script>
<script src="/assets/f87d6ddf/js/jquery.pjax.js"></script>

if($.support.pjax){
	$(document).pjax('[data-pjax=1] a, a[data-pjax=1]', '#pjax-container',{
	 	timeout: 6000,
	 	fragment:'#pjax-content',
 		scrollTo: false
	});
 		
 	$(document).on('pjax:send', function() {
        //在pjax发送请求时,显示loading动画层
    });
 		
    $(document).on('pjax:complete', function() {
        //在pjax处理完成后,隐藏loading动画层
        //由于速度太快会导到loading层闪烁,影响体验,所以在此加上500毫秒延迟
        
         //PS: 因为重新渲染页面, 注意自己写的js会不会失效!!!
    });
}

/* 
 * pjax 示例:
 * $(document).pjax('a.pjaxlink', '#Content', {fragment:'#ToInsert', timeout:5000});
 * 监控所有class为pjaxlink的链接,采用pjax更新链接页面中id为ToInsert的容器内容到本页面中id为Content的容器中。
 * 若获取内容时间超过5秒,则直接跳转.
 * 
 * pjax options:
timeout: 650,     ajax timeout in milliseconds after which a full refresh is forced
push: true,         use pushState to add a browser history entry upon navigation
replace: false,     replace URL without adding browser history entry
maxCacheLength: 20,         maximum cache size for previous container contents
version: '0.1',             a string or function returning the current pjax version
scrollTo: 0,         vertical position to scroll to after navigation. To avoid changing scroll position, pass false.
type: "GET",         see $.ajax
dataType: "html",    see $.ajax
container:             CSS selector for the element where content should be replaced
url: '',             link.href     a string or function that returns the URL for the ajax request
target:,             link     eventually the relatedTarget value for pjax events
fragment:'#pjax-container',         CSS selector for the fragment to extract from ajax response 
*/


    关键点解析:

    ① 判断浏览器是否支持pjax:  if( $.support.pjax )

    ② 指定为哪些a标签绑定pjax监听事件,示例中是'[data-pjax=1] a, a[data-pjax=1]'。

一般pjax只能绑定在a标签上,因为pjax会用到a标签的href,当然js模拟点击触发pjax的方式除外(这里是个人理解,可能不准确)。

    ③ 指定容器:'#pjax-container'。被替换的容器

        指定容器:'#pjax-content'。替换的容器

        pjax请求完成时,先把页面中ID为pjax-container容器中的所有内容delete,然后把响应的内容中ID为pjax-content的内容insert到#pjax-container中去。


3、pushState,  pushState不知怎么翻译好,就保持原样好了。这步操作不需要用户参与,都由插件完成。pushState请求完成后主要做了三个动作:

    ① 将浏览器地址栏值替换成用户点击的a的href

    ② 如果请求响应的内容中含有<title>XXXX</title>,则替换网页标题

    ③ 将State push到浏览器浏览历史记录中, 使后退按钮生效!


4、对应后端代码

public function actionSearch(){
    ......
    ......
    if( Yii::$app->request->isPjax )
        return $this->renderPartial('list',   
            'items' => [], 
            'filter'=> [], 
            'pages' => new Pagination()
        ]);
    else
        return $this->render('list', 
            'items' => [], 
            'filter'=> [], 
            'pages' => new Pagination()
        ]);
}

后端代码随便贴的,开发者需要根据请求方式返回不同的数据,这使服务端的支持相对变复杂



OK,Pjax用法基本就是这样,那么在Yii2中我们怎么使用呢? 非常简单,要有yii2-pjax扩展支持

控制器代码可以做到不做任何修改:

QQ图片20160925163553.png

在视图文件中。

use yii\widgets\Pjax;


<?php Pjax::begin(); ?>

    <?= GridView::widget([
        ......
        ......
        ......
    ]); ?>
    
<?php Pjax::end(); ?>



为什么要用pjax? 

(转:https://my.oschina.net/sub/blog/123447

pjax有好几个好处:

  • 用户体验提升。

    页面跳转的时候人眼需要对整个页面作重新识别, 刷新部分页面的时候, 只需要重新识别其中一块区域。 同时, 由于刷新部分页面的时候提供了一个loading的提示, 以及在刷新的时候旧页面还是显示在浏览器中, 用户能够容忍更长的页面加载时间。

  • 极大地减少带宽消耗和服务器消耗。

    由于只是刷新部分页面, 大部分的请求(css/js)都不会重新获取, 网站带有用户登录信息的外框部分都不需要重新生成了。 虽然我没有具体统计这部分的消耗, 我估计至少有40%以上的请求, 30%以上的服务器消耗被节省了。

坏处我觉得也有:

  • IE6等历史浏览器的支持

    虽然我没有实际测试, 但是由于pjax利用到了新的标准, 旧的浏览器兼容会有问题。 不过pjax本身支持fallback, 当发现浏览器不支持该功能的时候, 会回到原始的页面跳转上面去。

  • 复杂的服务器端支持

    服务器端需要根据过来的请求, 判断是作全页面渲染还是部分页面渲染, 相对来说系统复杂度增大了。 不过对于设计良好的服务器代码, 支持这样的功能不会有太大的问题。

综合起来, 由于用户体验和资源利用率的提升, 坏处是可以完全得到弥补的。  我强烈推荐大家使用。


如果文章对您有所帮助,希望继续支持我们,您的支持是我们最大的动力 ¥打赏
标签: yii2 pjax yii2-pjax
声明:文章内容由作者原创或整理,未经允许,不得转载!
  • 评论于 2016-09-26 11:38:56

    先赞一个

    回复于 2016-09-26 14:58:55 回复
    ^_^
    回复
  • 评论于 2016-09-26 11:30:36

    花了好长时间整理的, 最后发现理论偏多实际用处的少。 大家还有别的建议吗,欢迎留言。

    回复
您需要登录后才可以评论。登录 | 立即注册