jQuery 進階二
一、使用jQuery中的Ajax實現無刷新分頁
1. 分頁原理
php中查詢所有數據的語句:
select * from 數據表
分頁原理:
假設每一頁顯示 3 條數據,使用變量$pageSize
表示,即$pageSize=3
當前的頁碼從地址欄獲取,如果地址欄存在p參數,就獲取它,如果不存在p參數,默認是第1頁,所以:
第一頁:select * from 數據表 limit 0,3;
第二頁:select * from 數據表 limit 3,3;
第三頁:select * from 數據表 limit 6,3;
…
第 p頁:select * from 數據表 limit ($p-1)*$pageSize,$pageSize;
2. 分頁數據查詢
<?php
//還是使用省市縣三表
//連接數據庫
$pdo = new PDO('mysql:host=localhost; dbname=test; charset=utf8;','root');
//定義變量
$pageSize = 3;
$p = $_GET['p']?$_GET['p']:1;
//$p = $_GET['p'] ?? 1;
//sql語句
$sql = "select * from sheng limit ".($p-1)*$pageSize.','.$pageSize;
//預處理sql語句
$stmt = $pdo->prepare($sql);
//執行sql語句
$stmt->execute();
//獲取結果集
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
//格式化php格式
echo '<pre>';
//輸出
print_r($data);
使用 postman 發送請求看看結果:
3. 輸出數據、分頁並實現分頁的渲染
PHP
<?php
/* 獲取數據表數據 */
//還是使用省市縣三表
//連接數據庫
$pdo = new PDO('mysql:host=localhost; dbname=test; charset=utf8;','root');
//定義變量
$pageSize = 3;
$p = $_GET['p']?$_GET['p']:1;
//$p = $_GET['p'] ?? 1;
//sql語句
$sql = "select * from sheng limit ".($p-1)*$pageSize.','.$pageSize;
//預處理sql語句
$stmt = $pdo->prepare($sql);
//執行sql語句
$stmt->execute();
//獲取結果集
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
//格式化php格式
//echo '<pre>';
//輸出
//print_r($data);
/* 製作分頁頁碼 */
//上一頁,小於1就不能繼續上一頁,否則就是按照$p-1來進行頁數跳轉
if($p<=1){
$prev = "<a href='javascript:void(0);'>上一頁</a>";
}else{
$prev = "<a href='?p=".($p-1)."'>上一頁</a>";
}
//下一頁,獲取數據表條數,向上取整
$sql_count = "select count(*) from sheng";
//預處理sql語句
$stmt = $pdo->prepare($sql_count);
//執行sql語句
$stmt->execute();
//獲取總數
$count = $stmt->fetchColumn(); //總記錄數
//向上取整
$maxPage = ceil($count/$pageSize);
if($p<$maxPage){
$next = "<a href='?p=".($p+1)."'>下一頁</a>";
}else{
$next = "<a href='javascript:void(0);'>下一頁</a>";
}
/* 處理,響應 */
$page = $prev.$next;
$res = [$data,$page];
echo json_encode($res);
?>
使用postman查看結果:
HTML
<!-- 渲染 -->
<h2 align="center">無刷新分頁</h2>
<table border="1" cellspacing="0" cellpadding="2" width="600" align="center" rules="all">
<thead>
<tr>
<th>PID</th>
<th>Pcode</th>
<th>Pname</th>
</tr>
</thead>
<tbody>
<!-- 數據 -->
</tbody>
</table>
<p align="center">
<!-- 分頁 -->
</p>
4. 無刷新分頁獲取第一頁數據
使用jQuery中的Ajax進行請求,並將數據遍歷到html中。
/* 獲取第一頁數據 */
$(function(){
$.get('page.php',{p:1},function(res){
/* 獲取數據表數據 */
var data = res[0];
/* 獲取分頁 */
var page = res[1];
/* 遍歷數據表數據,構建html */
var str = '';
$.each(data,function(i,val){
str+='<tr>';
str+='<td>'+val.PID+'</td>';
str+='<td>'+val.Pcode+'</td>';
str+='<td>'+val.Pname+'</td>';
str+='</tr>';
})
$('tbody').html(str);
$('p').html(page);
},'json')
});
看看效果:
5. 實現無刷新分頁
要實現無刷新的分頁,必須讓a標籤不能跳轉纔可以。所以將a標籤的href屬性值都寫成javascript:void(0);
又因爲,點擊a標籤的時候,必須知道你要請求哪一頁的數據,所以在a標籤上還必須體現出請求的頁碼。
修改PHP
再次後臺查看html代碼:
因此根據 pp 的值進行跳轉:
原理:根據 pp 的值,發送Ajax請求,再次更新頁面數據。
值得注意的是:<a>
是後期加載而來,綁定事件是需要使用 on 方法。
案例總體:
HTML
<!-- 渲染 -->
<h2 align="center">無刷新分頁</h2>
<table border="1" cellspacing="0" cellpadding="2" width="600" align="center" rules="all">
<thead>
<tr>
<th>PID</th>
<th>Pcode</th>
<th>Pname</th>
</tr>
</thead>
<tbody>
<!-- 數據 -->
</tbody>
</table>
<p align="center">
<!-- 分頁 -->
</p>
JavaScript
$(function(){
/* 獲取第一頁數據 */
$.get('page.php',{p:1},function(res){
/* 獲取數據表數據 */
var data = res[0];
/* 獲取分頁 */
var page = res[1];
/* 遍歷數據表數據,構建html */
var str = '';
$.each(data,function(i,val){
str+='<tr>';
str+='<td>'+val.PID+'</td>';
str+='<td>'+val.Pcode+'</td>';
str+='<td>'+val.Pname+'</td>';
str+='</tr>';
})
$('tbody').html(str);
$('p').html(page);
},'json');
/* 無刷新分頁 */
//點擊a 標籤,獲取對應的頁的數據。因爲a標籤是後加載過來的,所以必須使用on事件
$(document).on('click','a',function(){
/* 獲取pp的 value 值 */
var pp = $(this).attr('pp'); //獲取標籤的屬性值
/* 再次發送請求 */
$.get('page.php',{p:pp},function(res){
/* 獲取數據表數據 */
var data = res[0];
/* 獲取分頁 */
var page = res[1];
/* 遍歷數據表數據,構建html */
var str = '';
$.each(data,function(i,val){
str+='<tr>';
str+='<td>'+val.PID+'</td>';
str+='<td>'+val.Pcode+'</td>';
str+='<td>'+val.Pname+'</td>';
str+='</tr>';
})
$('tbody').html(str);
$('p').html(page);
},'json');
})
});
PHP(page.php)
<?php
/* 獲取數據表數據 */
//還是使用省市縣三表
//連接數據庫
$pdo = new PDO('mysql:host=localhost; dbname=test; charset=utf8;','root');
//定義變量
$pageSize = 3;
$p = $_GET['p']?$_GET['p']:1;
//$p = $_GET['p'] ?? 1;
//sql語句
$sql = "select * from sheng limit ".($p-1)*$pageSize.','.$pageSize;
//預處理sql語句
$stmt = $pdo->prepare($sql);
//執行sql語句
$stmt->execute();
//獲取結果集
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
//格式化php格式
//echo '<pre>';
//輸出
//print_r($data);
/* 製作分頁頁碼 */
//上一頁,小於1就不能繼續上一頁,否則就是按照$p-1來進行頁數跳轉
// if($p<=1){
// $prev = "<a href='javascript:void(0);'>上一頁</a>";
// }else{
// $prev = "<a href='?p=".($p-1)."'>上一頁</a>";
// }
if($p<=1){
$prev = "<a href='javascript:void(0);' pp='1'>上一頁</a>";
}else{
$prev = "<a href='javascript:void(0);' pp='".($p-1)."'>上一頁</a>";
}
//下一頁,獲取數據表條數,向上取整
$sql_count = "select count(*) from sheng";
//預處理sql語句
$stmt = $pdo->prepare($sql_count);
//執行sql語句
$stmt->execute();
//獲取總數
$count = $stmt->fetchColumn(); //總記錄數
//向上取整
$maxPage = ceil($count/$pageSize);
// if($p<$maxPage){
// $next = "<a href='?p=".($p+1)."'>下一頁</a>";
// }else{
// $next = "<a href='javascript:void(0);'>下一頁</a>";
// }
if($p<$maxPage){
$next = "<a href='javascript:void(0);' pp='".($p+1)."'>下一頁</a>";
}else{
$next = "<a href='javascript:void(0);' pp='$maxPage'>下一頁</a>";
}
/* 處理,響應 */
$page = $prev.$next;
$res = [$data,$page];
echo json_encode($res);
?>
效果:
二、跨域請求
1. 跨域請求的三種方法
與JavaScript相同,實現跨域請求的方法有:
- 使用代理的方法
- 使用cors方式實現請求(設置訪問權限)
參考博客: https://blog.csdn.net/Errrl/article/details/104088491
- 使用JSONP技術
2. JSONP技術
Jsonp(JSON with Padding) 是 json 的一種"使用模式",通俗的講,jsonp可以通過html標籤中的src屬性訪問另外域的內容,可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。
什麼樣的HTML標籤有src屬性:
-
img
-
script
-
iframe
實例:
www.ajaxtest.com:03kuayu.html
HTML
<input type="button" value="請求" id="btn">
javaScript
document.getElementById('btn').onclick = function(){
/* 創建一個script標籤,因爲script含有src屬性 */
var scr = document.createElement('script');
scr.src = 'http://www.jstest.com/03kuayu.php';
document.body.appendChild(scr);
}
//創建一個函數接受響應數據
function fn(res){
console.log(res);
}
www.jstest.com:03kuayu.php
<?php
//echo "alert(123)";
//可以在php中echo js代碼
//echo "fn()"; //告訴瀏覽器執行函數fn
$arr = [
['id'=>1,'name'=>'yaodao'],
['id'=>2,'name'=>'jack']
];
/* 響應數據,告訴瀏覽器調用函數輸出數據 */
$res = json_encode($arr);
echo "fn($res)";
//在此調用函數fn,所以JavaScript中必須準備聲明fn函數來接收數據
同樣也可以將函數當作一個值進行傳遞。這樣可以避免函數名不確認的情況。
修改JavaScript代碼:
document.getElementById('btn').onclick = function(){
/* 創建一個script標籤,因爲script含有src屬性 */
var scr = document.createElement('script');
scr.src = 'http://www.jstest.com/03kuayu.php?callback=fn';
document.body.appendChild(scr);
}
//創建一個函數接受響應數據
function fn(res){
console.log(res);
}
修改PHP代碼:
<?php
//echo "alert(123)";
//可以在php中echo js代碼
//echo "fn()"; //告訴瀏覽器執行函數fn
$arr = [
['id'=>1,'name'=>'yaodao'],
['id'=>2,'name'=>'jack']
];
/* 響應數據,告訴瀏覽器調用函數輸出數據 */
$res = json_encode($arr);
/* 多一步,獲取地址欄的參數 */
$fn = $_GET['callback'];
echo "$fn($res)";
//在此調用函數fn,所以JavaScript中必須準備聲明fn函數來接收數據
3. jQuery 中的 Ajax 跨域請求
將jQuery Ajax請求中的第三個參數修改成 ‘jsonp’ 即可。
例如:
/* 方法一 */
$.get('http://www.jstest.com/03kuayu.php?fn=?', {}, function(e){
//e就是另外域的PHP返回的數據
}, 'jsonp');
/* 方法二 */
$.ajax({
type:'get',
data:{},
dataType:'jsonp',
url:'http://www.js.com/jsonp.php?fn=?',
success:function(e){
//處理返回的數據
}
});
/* 方法三:專屬jsonp */
$.getJSON(
'http://www.js.com/jsonp.php?callback=?',
function(e){
//e接受返回的數據
}
);
使用方法三,實現 jsonp 跨域請求
修改JavaScript代碼:
$(function () {
$('btn').click(function () {
var url = "http://www.jstest.com/03kuayu.php?callback=?";
$.getJSON(url, function (res) {
console.log(res);
})
})
})
PHP
<?php
//echo "alert(123)";
//可以在php中echo js代碼
//echo "fn()"; //告訴瀏覽器執行函數fn
$arr = [
['id'=>1,'name'=>'yaodao'],
['id'=>2,'name'=>'jack']
];
/* 響應數據,告訴瀏覽器調用函數輸出數據 */
$res = json_encode($arr);
/* 多一步,獲取地址欄的參數 */
$fn = $_GET['callback'];
echo "$fn($res)";
//在此調用函數fn,所以JavaScript中必須準備聲明fn函數來接收數據
結果:
三、插件的編寫
1. $.fn.extend();
使用此種方法需要傳遞對象形式的參數,對象中的每一個成員都是一個插件。
實例:
HTML
<!-- 測試對象 -->
<div style="color:blue">hello</div>
<p>123</p>
JavaScript
$(function(){
$.fn.extend({
red:function(){
$(this).css('color','red').css('background-color','red');
},
yellow:function(){
$(this).css('color','yellow').css('background-color','yellow');
},
//...自定義插件...
});
//測試
$('div').red();
$('p').yellow();
//注意:可以鏈式操作
})
效果:
2.$fn.xxx = function(){}
這種語法,只能夠定義一個插件。
實例:
HTML
<!-- 測試對象 -->
<div style="color:blue">hello</div>
<p>123</p>
JavaScript
$(function(){
$.fn.newCss = function(color){
//$(this)表示調用插件的對象
$(this).css('color',color.x).css('background-color',color.y)
return $(this);//如果不return,無法鏈式操作
};
$('div').newCss({x:'white',y:'red'}).wrap($('<div></div>'));
})
效果:
注意:wrap($('<div></div>'))
包裹標籤對象
3. 自定義插件(插件的應用)
(1)創建目錄結構
將box.js、jquery-3.3.1.js引入到html中。
(2)HTML+CSS
HTML
<body style="width:2000px; height:2000px;">
<div id="left">
<div class="title">這是標題部分 <span>×</span></div>
<div class="content">這是內容區</div>
</div>
<div id="center">
<div class="title">這是標題部分 <span>×</span></div>
<div class="content">這是內容區</div>
</div>
<div id="right">
<div class="title">這是標題部分 <span>×</span></div>
<div class="content">這是內容區</div>
</div>
</body>
CSS
*{
padding:0;
margin:0;
border:0 none;
}
#left,#center,#right{
border:solid 1px black;
width:200px;
height:120px;
position: absolute;
display: none;
}
.title{
background-color: #92b8b1;
height:24px;
line-height: 24px;
padding:5px;
border-bottom: solid 1px black;
}
.content{
padding:5px;
}
.title span{
float: right;
cursor: pointer;
}
(3)調用插件
JavaScript
$(function () {
//自己的JS,調用插件,顯示窗口
$('#left').box({zuo:'left', shang:'center'});
$('#center').box({zuo:'center', shang:'center'},'fadeOut');
$('#right').box({zuo:'right', shang:'bottom'},'slide');
});
(4)完成各個窗口的顯示
box.js
$.fn.box = function (position) {
//參數樣式position = {zuo:'left',shang:'center'}
var box = $(this);
//獲取傳參位置
var zuo = position.zuo;
var shang = position.shang
//聲明真實的left和top值
var trueLeft;
var trueTop;
//獲取瀏覽器窗口的寬度與高度
var win = $(window);
var winWidth = win.width();
var winHeight = win.height();
//獲取div的寬度、高度
var boxWidth = box.outerWidth();
var boxHeight = box.outerHeight();
//獲取滾動條的距離
var scrollLeft = win.scrollLeft();
var scrollTop = win.scrollTop();
//以九宮格的位置顯示
//可選的zuo值有:left center right
//可選的shang值有:top center bottom
if (zuo == 'left') {
trueLeft = 0 + scrollLeft + 'px';
} else if (zuo == 'center') {
trueLeft = (winWidth - boxWidth) / 2 + scrollLeft + 'px';
} else if (zuo == 'right') {
trueLeft = winWidth - boxWidth + scrollLeft + 'px';
}
if (shang == 'top') {
trueTop = 0 + scrollTop + 'px';
} else if (shang == 'center') {
trueTop = (winHeight - boxHeight) / 2 + scrollTop + 'px';
} else if (shang == 'bottom') {
trueTop = winHeight - boxHeight + scrollTop + 'px';
}
//console.log(trueLeft,trueTop);
box.css('left', trueLeft).css('top', trueTop).show();
}
得到的效果:
(5)當瀏覽器改變時或滾動條滾動時,保持div的位置不變
實現原理:對獲取的計算參數進行函數封裝,當瀏覽器改變時或滾動條滾動時,調用函數重新計算。
封裝三個函數:
第一個:獲取瀏覽器的寬高及滾動條的滾動距離(原因:當瀏覽器改變時或滾動條滾動時,數值會發生改變,所以要重新計算。)
第二個:計算真實的left和真實的top值。
第三個:窗口的顯示
修改box.js:
$.fn.box = function (position) {
//參數樣式position = {zuo:'left',shang:'center'}
var box = $(this);
//獲取傳參位置
var zuo = position.zuo;
var shang = position.shang
//聲明真實的left和top值
var trueLeft;
var trueTop;
//獲取div的寬度、高度
var boxWidth = box.outerWidth();
var boxHeight = box.outerHeight();
//獲取瀏覽器窗口的寬度與高度
var win;
var winWidth;
var winHeight;
//獲取滾動條的距離
var scrollLeft;
var scrollTop;
/* 封裝獲取信息函數 */
function getVal(){
//獲取瀏覽器窗口的寬度與高度
win = $(window);
winWidth = win.width();
winHeight = win.height();
//獲取滾動條的距離
scrollLeft = win.scrollLeft();
scrollTop = win.scrollTop();
}
/* 封裝計算函數 */
function calculate(){
//以九宮格的位置顯示
//可選的zuo值有:left center right
//可選的shang值有:top center bottom
if (zuo == 'left') {
trueLeft = 0 + scrollLeft + 'px';
} else if (zuo == 'center') {
trueLeft = (winWidth - boxWidth) / 2 + scrollLeft + 'px';
} else if (zuo == 'right') {
trueLeft = winWidth - boxWidth + scrollLeft + 'px';
}
if (shang == 'top') {
trueTop = 0 + scrollTop + 'px';
} else if (shang == 'center') {
trueTop = (winHeight - boxHeight) / 2 + scrollTop + 'px';
} else if (shang == 'bottom') {
trueTop = winHeight - boxHeight + scrollTop + 'px';
}
}
/* 封裝顯示窗口函數 */
function show(){
box.css('left', trueLeft).css('top', trueTop).show();
}
/* 初始化顯示一次 */
getVal();
calculate();
show();
/* 綁定瀏覽器改變大小事件、滾動條滾動事件 */
win.scroll(function(){
/* 重新計算與顯示 */
getVal();
calculate();
show();
});
win.resize(function(){
/* 重新計算與顯示 */
getVal();
calculate();
show();
});
}
最終效果:
滾動滾動條
縮小瀏覽器窗口