文档章节

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

eechen
 eechen
发布于 2016/12/08 17:15
字数 787
阅读 1354
收藏 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的.

© 著作权归作者所有

共有 人打赏支持
eechen

eechen

粉丝 986
博文 107
码字总数 55962
作品 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 笑而不语:relieved:
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
0
2
PHP+jQuery实现Ajax分页效果:jPaginate插件的应用

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

mickelfeng
2013/12/28
0
2
Pjax是什么以及为什么推荐大家用

什么是pjax? 现在很多网站( facebook, twitter)都支持这样的一种浏览方式, 当你点击一个站内的链接的时候, 不是做页面跳转, 而是只是站内页面刷新。 这样的用户体验, 比起整个页面都闪一...

Sub
2013/04/17
0
33
关于pjax方式无刷新加载网页?

pjax使用不成功啊,已经成功发出了pjax请求了,但是瞬间请求就abort,然后又采用刷新的方式加载,什么问题? 我的做法: 1.加入jquery、pjax的js包 2.前台对a标签作pjax处理,主要是a标签选择...

小薇
2013/04/23
3.5K
5
习习风/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

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周日乱弹 —— 小心着凉 @红薯

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @莱布妮子:5.33起,其声呜呜然,如怨如慕,如泣如诉。余音袅袅,不绝如缕。分享Arch Enemy的单曲《Bridge Of Destiny (2009)》 《Bridge Of...

小小编辑
13分钟前
6
0
what f,,

anlve
53分钟前
0
0
初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
10
0
现场看路演了!

HiBlock
昨天
19
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部