PHP+jQuery寥寥几行代码轻松实现百度搜索那样的无刷新PJAX的分页列表和导航链接
博客专区 > eechen 的博客 > 博客详情
PHP+jQuery寥寥几行代码轻松实现百度搜索那样的无刷新PJAX的分页列表和导航链接
eechen 发表于1年前
PHP+jQuery寥寥几行代码轻松实现百度搜索那样的无刷新PJAX的分页列表和导航链接
  • 发表于 1年前
  • 阅读 1182
  • 收藏 9
  • 点赞 1
  • 评论 9

腾讯云 技术升级10大核心产品年终让利>>>   


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的.

标签: php 分页 PJAX jQuery
共有 人打赏支持
eechen
粉丝 928
博文 106
码字总数 55593
作品 1
评论 (9)
狂暴的蜗牛君
几行代码。。。。。
eechen

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

几行代码。。。。。
关键就2行:
分页导航链接: echo page_nav($_GET['page']);
PJAX无刷新加载: $(document).pjax("a:not([target='_blank'])", ".pjax");
踏雪无痕丶
自黑?
西南茂
厉害了我的天pjax。。。
notreami
web上直接js就够了,php用处太小,扔了吧。。
DevYang
Node + CoffeeScript 笑而不语:relieved:
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的界面编程之所以流行,很大程度也是因为它们的"热部署"特性,修改代码刷新页面就生效了.
xiaose1205
哎,还在自我陶醉。估计是刚毕业的
×
eechen
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: