前端点滴(jQuery)(三)

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查看结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RnVDt2Eh-1580496937003)(G:\java\blog\1580457933531.png)]

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相同,实现跨域请求的方法有:

  1. 使用代理的方法
  2. 使用cors方式实现请求(设置访问权限)

参考博客: https://blog.csdn.net/Errrl/article/details/104088491

  1. 使用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();
    });
}

最终效果:

滚动滚动条
在这里插入图片描述

缩小浏览器窗口
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值