文档章节

PHP+jQuery寥寥几行代码轻松实现百度搜索那样的无刷新PJAX的分页列表和导航链接

eechen
 eechen
发布于 2016/12/08 17:15
字数 787
阅读 2K
收藏 11

#程序员薪资揭榜#你做程序员几年了?月薪多少?发量还在么?>>>


PHP寥寥几行代码轻松实现百度搜索那样的分页列表和导航链接,某些语言的拥趸哭晕在厕所.

<?php

$app = array(
	'db_prefix' => 'phpbest_',
	'db_sqlite' => '/dev/shm/phpbest/phpbest.db3',
);

//数据库连接单例
function db() {
	global $app;
	static $db;
	if($db) {
		return $db;
	} else {
		try {
			$db = new PDO('sqlite:'.$app['db_sqlite']);
		} catch(PDOException $e) {
			echo $e->getMessage();
			exit();
		}
		return $db;
	}
}

//分页导航链接
function page_nav($page, $page_size = 10, $before = 5, $after = 4) {
	$page = intval($page);
	$page_size = intval($page_size);
	global $app;
	$db = db();
	$table = $app['db_prefix'].'post';
	$arr = $db->query("SELECT count(id) FROM $table")->fetchAll(PDO::FETCH_NUM);
	$records = $arr[0][0]; //记录数
	$pages = ceil($records/$page_size); //页数
	if($pages == 0) return;
	if($page <= 0 || $page > $pages) return;
	
	$html = '<p>当前页:前输出5页,后输出4页</p>';
	$html .= '<a href="?page=1">最前</a>';
	if($page != 1) { $html .= '<a href="?page='.($page - 1).'">上一页</a>'; }
	if($page <= $before) { for($i = 1; $i < $page; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
	else { for($i = $page - $before; $i < $page; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
	$html .= '<a href="?page='.$page.'">第'.$page.'页(当前页)</a>';
	if($pages >= $page + $after) { for($i = $page + 1; $i <= $page + $after; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
	else { for($i = $page + 1; $i <= $pages; $i++) { $html .= '<a href="?page='.$i.'">第'.$i.'页</a>'; } }
	if($page != $pages) { $html .= '<a href="?page='.($page + 1).'">下一页</a>'; }
	$html .= '<a href="?page='.$pages.'">最后</a>';
	return $html;
}

//分页列表内容
function page_list($page, $page_size = 10) {
	$page = intval($page);
	$page_size = intval($page_size);
	global $app;
	$db = db();
	$table = $app['db_prefix'].'post';
	$offset = ($page - 1) * $page_size;
	return $db->query("SELECT * FROM $table ORDER BY id DESC LIMIT $page_size OFFSET $offset")->fetchAll(PDO::FETCH_ASSOC);
}

?>

<div class="content pjax">
	<?php echo page_nav($_GET['page'], 2); ?>
	<ul>
	<?php
		foreach(page_list($_GET['page'], 2) as $v) {
			echo '<li>'.$v['id'].'</li>';
			echo '<li>'.$v['title'].'</li>';
			echo '<li>'.$v['content'].'</li>';
			echo '<li>'.date('Y-m-d H:i:s', strtotime($v['date'])).'</li><br>';
		}
	?>
	</ul>
</div>
<script type="text/javascript" src="jquery.pjax.js"></script>
<script>
(function($){
	$(function(){
		//调用插件,用户点击链接后局部刷新class为pjax(要求唯一)的块并写入历史记录
		$(document).pjax("a:not([target='_blank'])", ".pjax");
	});
})(jQuery);
</script>

jquery.pjax.js是我写的一个插件,代码简单到差不多每个人都看得懂:

/* jquery.pjax.js */
(function($){
	$.fn.pjax = function(selector, container) {
		
		//IE8之流不支持HTML5 onpopstate,自然不会执行插件
		if("onpopstate" in window) {
			
			//AJAX加载函数
			var load = function(href) {
				var time = 600;
				$(document).trigger("pjax:start", [time]); //执行开发者的自定义事件(如:显示加载进度条)
				var start = new Date().getTime();
				$.ajax({
					type: "GET",
					url: href,
					data: {_pjax_: new Date().getTime()}
				}).done(function(data){
					//在回调函数中解析出head中的title和body中的指定块并更新(这样服务器端就不需要改变输出格式)
					var dom = $("<div>").html(data);
					document.title = dom.find("title").first().text();
					$(container).first().html(dom.find(container).first().html());
					var spend = new Date().getTime() - start;
					setTimeout(function(){
						$(document).trigger("pjax:done"); //执行开发者的自定义事件(如:隐藏加载进度条)
					}, spend >= time ? 0 : time - spend);
				});
			};
			
			history.replaceState({href:location.href}, "", location.href);
			
			window.onpopstate = function() {
				//用户点击后退和前进按钮时触发该事件
				if(history.state != null) {
					load(history.state.href);
				}
			}
			
			$(container).on("click", selector, function(e){
				//用户点击页面链接时改变地址栏(URL)并写入历史记录以及AJAX加载页面
				e.preventDefault();
				var href = $(this).attr("href");
				if(href != "javascript:void(0)") {
					history.pushState({href:href}, "", href);
					load(href);
				}
			});
		}
	};
})(jQuery);

不支持PJAX的浏览器如IE8会自动退化成原始的链接打开的方式,所以采用PJAX的站点也是可以兼容IE8的.

© 著作权归作者所有

eechen

eechen

粉丝 1041
博文 107
码字总数 56154
作品 1
深圳
私信 提问
加载中

评论(9)

xiaose1205
xiaose1205
哎,还在自我陶醉。估计是刚毕业的
eechen
eechen 博主
@notreami @DevYang
JS在服务器的运行环境(Node)跟浏览器差别很大.
在服务器Node是以一个独立的守护进程运行,
代码稍有不慎就可能导致进程崩溃退出,
而且修改代码需要重启Node进程才能生效(那些自动化工具nodemon/pm2本质也是重启服务).
服务器的PHP跟浏览器的JS反而更像,都是提供一个比较稳定的容器来执行脚本.
比如你很难写出让PHP容器(如PHP-FPM和Apache)发生崩溃的PHP代码.
浏览器也会尽量避免因为网站JS的问题导致的崩溃.
比如浏览器Chrome跟PHP-FPM用的都是多进程架构,
子进程崩溃并不会影响主进程,主进程可以重新启动一个子进程提供服务.

PHP的热部署特性大大方便了开发和运维,这点是Java等其他语言(包括Python/RoR/Node.JS)所不能媲美的.
基于HTML/CSS/JS的界面编程之所以流行,很大程度也是因为它们的"热部署"特性,修改代码刷新页面就生效了.
DevYang
DevYang
Node + CoffeeScript 笑而不语😌
notreami
notreami
web上直接js就够了,php用处太小,扔了吧。。
西南茂
西南茂
厉害了我的天pjax。。。
踏雪无痕丶
踏雪无痕丶
自黑?
eechen
eechen 博主

引用来自“蜗牛君”的评论

几行代码。。。。。
关键就2行:
分页导航链接: echo page_nav($_GET['page']);
PJAX无刷新加载: $(document).pjax("a:not([target='_blank'])", ".pjax");
狂暴的蜗牛君
狂暴的蜗牛君
几行代码。。。。。
php整合pjax(pushstate+ajax)实现无刷新页面

PJAX效果 通过url可以跟踪ajax的动态加载内容。这种技术尤其在two step view布局的视图中有很大的好处。无刷新加载页面,意味着响应速度和用户体验得到了极大的提升,在静态脚本和通用模块比...

_EKC
2012/10/01
6.7K
2
PHP+jQuery实现Ajax分页效果:jPaginate插件的应用

jPaginate是基于jQuery的动感滚动分页插件,它的表现形式是像分页的按钮一样,非常有意思的是这些按钮却可以滚动,可以通过单击或鼠标滑向点两侧的小箭头来控制按钮的前后滚动。 调用jPagina...

mickelfeng
2013/12/28
233
2
基于 Beego 开发的后台管理系统 - gardens

gardens是基于Beego开发的易用、易扩展、界面友好的轻量级功能权限管理系统。 前端框架基于AdminLTE2进行资源整合,包含了多款优秀的插件,是笔者对多年后台管理系统开发经验精华的萃取。 本...

yunnet
2018/10/31
4.5K
0
黄聪:Pjax无刷新跳转页面实现,支持超链接与表单提交

什么是pjax? 当你点击一个站内的链接的时候,不是做页面跳转,而是只是站内页面刷新。这样的用户体验,比起整个页面都闪一下来说, 好很多。 其中有一个很重要的组成部分, 这些网站的ajax刷...

osc_csyrqhea
2018/03/26
4
0
习习风/pjaxpage

Download the compressed, production pjaxPage 1.1 Download the uncompressed, development pjaxPage 1.1 1. Quick Start 1.1 HTML Code Here is the minimal HTML code to get pages work......

习习风
2017/09/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

vue组件大小写说明

https://cn.vuejs.org/v2/style-guide/#%E6%A8%A1%E6%9D%BF%E4%B8%AD%E7%9A%84%E7%BB%84%E4%BB%B6%E5%90%8D%E5%A4%A7%E5%B0%8F%E5%86%99%E5%BC%BA%E7%83%88%E6%8E%A8%E8%8D%90......

李超明
11分钟前
14
0
uni-app集成WebSocket

摘自: https://uniapp.dcloud.io/api/request/websocket?id=connectsocket uni.connectSocket(OBJECT) 创建一个 WebSocket 连接。 在各个小程序平台运行时,网络相关的 API 在使用前需要配置...

SummerGao
16分钟前
11
0
关于Oracle子查询各大用法详解

子查询 一.概述: 子查询:一个select语句,作为另一条select语句语法的一部分。 select语句语法: select distinct * | 字段 from 表名 where 查询条件 group by 分组字段 having 分组条件 ...

煌sir
17分钟前
20
0
您能说说序列化和反序列化吗?是怎么实现的?什么场景下需要它?

序列化和反序列化是Java中最基础的知识点,也是很容易被大家遗忘的,虽然天天使用它,但并不一定都能清楚的说明白。我相信很多小伙伴们掌握的也就几句概念、关键字(Serializable)而已,如果深...

费先森
21分钟前
26
0
可以让你用到老的IntelliJ idea 破解法子

看下效果图如下: 安装的时候选择试用,然后进入idea 下载插件 插件地址 然后将jetbrains-agent.jar文件拖入到idea中 然后重启 然后选择Activation code 然后就ojbk了...

布袋和尚_爱吃鱼
43分钟前
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部