# :-: 一、分頁原理
### 1、基本術語
* 記錄索引: 記錄在表中的位置,從0開始(與主鍵無關)
* 偏移量: 每頁顯示的起始位置
* 顯示數量: 每頁默認的顯示數量
```[mysql]
# 為了測試方便,我們先增加一些數據
INSERT INTO `user` VALUES (2, '13011113333', '洪七公', 'e10adc3949ba59abbe56e057f20f883e', 74, 1, 1, 1554282409);
INSERT INTO `user` VALUES (3, '18722223333', '黃蓉', 'e10adc3949ba59abbe56e057f20f883e', 17, 2, 1, 1554282409);
INSERT INTO `user` VALUES (4, '18722224444', '郭靖', 'e10adc3949ba59abbe56e057f20f883e', 23, 1, 1, 1554282409);
INSERT INTO `user` VALUES (5, '18722225555', '黃藥師', 'e10adc3949ba59abbe56e057f20f883e', 58, 1, 1, 1554282409);
INSERT INTO `user` VALUES (6, '18722226666', '周伯通', 'e10adc3949ba59abbe56e057f20f883e', 53, 1, 1, 1554282409);
INSERT INTO `user` VALUES (7, '18722227777', '楊過', 'e10adc3949ba59abbe56e057f20f883e', 1, 1, 1, 1554282409);
INSERT INTO `user` VALUES (8, '18722228888', '楊康', 'e10adc3949ba59abbe56e057f20f883e', 22, 1, 1, 1554282409);
INSERT INTO `user` VALUES (9, '18722229999', '歐陽鋒', 'e10adc3949ba59abbe56e057f20f883e', 60, 1, 1, 1554282409);
INSERT INTO `user` VALUES (10, '18733331111', '丘處機', 'e10adc3949ba59abbe56e057f20f883e', 69, 1, 1, 1554282409);
INSERT INTO `user` VALUES (11, '18733332222', '瑛姑', 'e10adc3949ba59abbe56e057f20f883e', 45, 1, 1, 1554282409);
INSERT INTO `user` VALUES (12, '18733333333', '王重陽', 'e10adc3949ba59abbe56e057f20f883e', 55, 1, 1, 1554282409);
INSERT INTO `user` VALUES (13, '18733334444', '穆念慈', 'e10adc3949ba59abbe56e057f20f883e', 19, 1, 1, 1554282409);
INSERT INTO `user` VALUES (14, '18733335555', '陳玄風', 'e10adc3949ba59abbe56e057f20f883e', 35, 1, 1, 1554282409);
INSERT INTO `user` VALUES (15, '18733336666', '曲靈風', 'e10adc3949ba59abbe56e057f20f883e', 42, 2, 1, 1554282409);
INSERT INTO `user` VALUES (16, '18733337777', '梅超風', 'e10adc3949ba59abbe56e057f20f883e', 32, 1, 1, 1554282409);
```
*****
### 2、SQL中的分頁關鍵字
* `LIMIT m OFFSET n`
* `LIMIT m`: 每頁顯示的記錄數量
* `OFFSET n`: 從指定的索引n開始顯示
```mysql
SELECT * FROM user;
SELECT * FROM user LIMIT 0,5;
SELECT * FROM user LIMIT 5,5;
SELECT * FROM user LIMIT 5 OFFSET 5;
```
*****
### 3、偏移量計算公式
* offset = num * (page - 1)
*****
# :-: 二、Ajax原理
### 1、Ajax 是什么
* Ajax: (Asynchronous Javascript And XML)異步JavaScript和XML
* Ajax: 是指一種創建交互式網頁應用的網頁開發技術
* Ajax 是一種用于創建快速動態網頁的技術
* Ajax 是一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術
* 通過在后臺與服務器進行少量數據交換,Ajax可以使網頁實現異步更新
* 這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新
*****
### 2、XMLHTTPRequest
* XMLHttpRequest是一個瀏覽器接口,使得Javascript可以進行HTTP(S)通信
* 我們最熟悉應用就是創建**AJAX**對象
*****
### 3、案例
* 在不刷新頁面的情況下, 從服務器獲取數據并渲染到html中
```php
# php代碼:get_cate.php
<?php
$pdo = new PDO('mysql:dbname=php', 'root','root');
$stmt = $pdo->prepare('SELECT * FROM `category`');
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo '<pre>' .print_r($result,true);
// echo json_encode($result);
```
```html
# index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>電影分類</title>
</head>
<body>
<button>電影分類</button>
<ul>
</ul>
</body>
<script>
var btn = document.getElementsByTagName('button').item(0);
// 創建 Ajax對象
var request = new XMLHttpRequest();
btn.addEventListener('click', getCate, false);
// btn點擊事件回調方法
function getCate(ev) {
// 監聽請求
request.addEventListener('readystatechange', callBack, false);
// 配置請求
request.open('GET', 'get_cate.php', true);
// 發送請求
request.send(null);
// 從當前按鈕上移除點擊事件, 防止重復點擊
ev.target.removeEventListener('click', getCate, false);
}
// Ajax的請求成功的回調方法
function callBack() {
if (request.readyState === 4) {
// 控制臺檢查
// console.log(request.responseText);
var data = JSON.parse(request.responseText);
// JSON 轉 JS對象
// console.log(data);
// 循環生成<li>
var ul = document.getElementsByTagName('ul').item(0);
data.forEach(function (index){
// console.log(index['alias']);
var li = document.createElement('li');
li.innerText = index['alias'];
ul.appendChild(li);
});
}
}
</script>
</html>
```
*****
# :-: 三、Ajax分頁
### 1. 服務器返回的數據格式
* COUNT 統計表中記錄的一個函數,返回匹配條件的行數
* CEIL 浮點數向上取正
* LEFT 從左開始截取字符串
* CONCAT 將多個字符串連接成一個字符串
```php
# php代碼:get_movies.php
<?php
// 獲取當前要顯示的頁數
$page = intval($_GET['p'] ?? 1);
$pdo = new PDO('mysql:dbname=php', 'root', 'root');
// 每頁顯示數量
$num = 5;
// 總頁數: 需要分二步, 第一求出總記錄數量, 第二總記錄數量除以每頁顯示的記錄數量,再向上取整
$sql = "SELECT CEIL(COUNT(`mov_id`)/{$num}) FROM `movies`";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$pages = $stmt->fetchColumn(0);
// 每頁的顯示起止位置: 偏移量
// 偏移量 = 當前顯示數量 * (當前頁碼 - 1)
$offset = $num * ($page - 1);
$sql = "SELECT `mov_id`,`name`, CONCAT(LEFT(`detail`,20),'...') AS `detail` FROM `movies` LIMIT {$num} OFFSET {$offset} ";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$movies = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode(['pages'=>$pages, 'movies'=>$movies]);
```
*****
### 2. 前端分頁條
```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>最新影視劇介紹</title>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid black;
}
thead > tr{
background-color: lightblue;
}
ul, li {
padding: 0;
margin: 5px auto;
list-style: none;
text-align: center;
overflow: hidden;
}
li {
display: inline-block;
width: 30px;
height: 20px;
border: 1px solid black;
margin-left: 3px;
}
li:hover {
background-color: lightblue;
cursor: pointer;
}
/*設置當前頁高亮樣式*/
.active {
background-color: lightblue;
}
</style>
</head>
<body>
<table>
<caption>最新影視劇介紹</caption>
<thead>
<tr>
<th>序號</th>
<th>片名</th>
<th>簡介</th>
</tr>
</thead>
<tbody id>
<!--這里顯示影視信息列表-->
<tr>
<td>3</td>
<td>如果可以這樣愛</td>
<td>一對已婚男女突然徇情自殺,以為可以結束這...</td>
</tr>
</tbody>
</table>
<ul>
<li class="active">1</li>
<li class="">2</li>
</ul>
</body>
</html>
```
### 3. 數據獲取與渲染
```php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>最新影視劇介紹</title>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid black;
}
thead > tr{
background-color: lightblue;
}
ul, li {
padding: 0;
margin: 5px auto;
list-style: none;
text-align: center;
overflow: hidden;
}
li {
display: inline-block;
width: 30px;
height: 20px;
border: 1px solid black;
margin-left: 3px;
}
li:hover {
background-color: lightblue;
cursor: pointer;
}
/*設置當前頁高亮樣式*/
.active {
background-color: lightblue;
}
</style>
</head>
<body>
<table>
<caption>最新影視劇介紹</caption>
<thead>
<tr>
<th>序號</th>
<th>片名</th>
<th>簡介</th>
</tr>
</thead>
<tbody id>
<!--這里顯示影視信息列表-->
</tbody>
</table>
<ul>
<!--這里翻頁-->
</ul>
</body>
</html>
<script>
// 獲取表格顯示區
var tbody = document.getElementsByTagName('tbody').item(0);
// 獲取頁碼顯示區
var ul = document.getElementsByTagName('ul').item(0);
// 當前頁碼: 默認顯示第一頁
var p = <?=$_GET['p'] ?? 1?>;
// 創建 Ajax對象
var request = new XMLHttpRequest();
// 監聽文檔的load事件,在頁面加載完成后通過Ajax方式獲取數據
window.addEventListener('load', showData, false);
// load事件方法
function showData() {
// 監聽Ajax成功回調
request.addEventListener('readystatechange', getData, false);
// 配置請求
request.open('GET', 'get_movies.php?p='+p, true);
// 發送請求
request.send(null);
}
function getData() {
if (request.readyState === 4) {
// console.log(request.responseText);
// 1. 獲取Ajax返回的數據并解析為JavaScript變量
var obj = JSON.parse(request.responseText);
var pages = obj['pages'];
var movies = obj['movies'];
// 2. 生成表格數據
var str = '';
movies.forEach(function (movie) {
str += '<tr>';
str += '<td>' + movie['mov_id']+ '</td>';
str += '<td>' + movie.name+ '</td>';
str += '<td>' + movie.detail+ '</td>';
str += '</tr>';
});
// 將數據添加到表格中
tbody.innerHTML = str;
// 性能優化建議: 使用文檔片段統一添加,以減少DOM操作,提升渲染效率
// var frag = document.createDocumentFragment();
// movies.forEach(function (movie) {
// var tr = document.createElement('tr');
// for (var key in movie) {
// var td = document.createElement('td');
// td.innerHTML = movie[key];
// tr.appendChild(td);
// }
// frag.appendChild(tr);
// });
// tbody.appendChild(frag);
// 3. 生成頁碼
for (var i = 1; i <= pages; i++) {
// 設置當前頁碼是否高亮?
var active = (i === p) ? 'active' : '';
ul.innerHTML += '<li class="'+ active +'">' + i + '</li>';
// 供參考的,規范的DOM語法
/*
var li = document.createElement('li');
li.appendChild(document.createTextNode(i.toString()));
if (p === i) li.classList.add('active');
ul.appendChild(li);
*/
}
}
}
// 給頁碼添加點擊事件
ul.addEventListener('click', set_page, false);
function set_page(ev) {
console.log(ev.target.innerText);
location.search = '?p=' + ev.target.innerText;
}
// 作業:
// 添加上一下, 下一頁功能, 注意判斷頁碼越界的問題, 例如到了第一頁再前翻怎么處理, 到了最后一頁再后翻如何處理?
</script>
```
- 序言
- PHP基礎
- 認識PHP
- 環境安裝
- PHP語法
- 流程控制
- PHP數組
- PHP函數
- PHP類與對象
- PHP命名空間
- PHP7新特性
- PHP方法庫
- PHP交互
- 前后端交互
- 項目常規開發流程
- MySQL數據庫
- 會話控制
- Ajax分頁技術
- 細說函數
- 類與對象
- 對象進階
- 類與對象進階
- OOP面向對象
- 設計模式
- 路由與模板引擎
- 異常類
- PHP爬蟲
- PHP抓取函數
- PHP匹配函數
- 正則表達式
- PHP字符串函數
- 抓取實戰
- PHP接口
- 了解接口
- PHP插件
- PHPSpreadsheet
- ThinkPHP6
- 安裝
- 架構
- 數據庫
- 數據庫操作
- 視圖
- 模版
- 模型
- 雜項
- 命令行
- 交互
- 微信小程序
- 介紹
- 配置
- 組件
- 交互
- API
- 其他知識
- 百度小程序
- 介紹
- 配置
- 組件
- 交互
- API
- 其他知識
- Linux
- 服務器上線流程
- 安裝svn
- MySQL
- 認識MySQL
- MySQL函數
- 雜項
- composer依賴管理工具