自己动手用Javascript写一个无刷新分页控件
.NET技术交流群:337901356 ,欢迎您的加入!
对 于一个用户体验好的网站来说,无刷新技术是很重要的,无刷新,顾名思义,就是局部刷新数据,有用过Asp.net Web Form技术开发网页的人,可能对服务器端(具有runat="server"属性)的控件的回发(PostBack)特性有一定的了解。我们知道,只要 一点击页面中的Asp.net按钮(可能是LinkButton,也可能是Button,还有可能是ImageButton等)都会引起整个页面的刷新, 这样的体验是非常不好的,因为点击按钮后导致的操作是重新给服务器发送一个请求,重新执行一次页面的服务端代码,重新生成html,然后响应生成的页面内 容,发回浏览器端。这样无形中增大了网络浏览,用户等待页面的响应时间增长等。 有时我们点击某个按钮目的只是为了某个区域的数据被更新,而其他的区域的数据不变,这个时候我们就可以使用Ajax技术(Asynchronous Javascript And XML)称为异步Javascript 和 XML. 但是往往我们站点中的数据不止一条,但又要有页面无刷新(其实是局部刷新)的效果,那么分页的时候我们就不能在网上去下载服务端的分页控件(如 AspNetPager)来进行分页,因为服务器端的分页控件会和后台相关联,只能通过Javascript代码来编写一个分页控件来进行分页。 废话不多话说,看分页代码。 为了证明是无刷新分页,这里我们page.html这个静态页面来呈现从数据库中取到的数据。 page.html页面代码如下
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link href="../分页控件/Page.css" rel="stylesheet" />
<script src="../分页控件/Page.js"></script>
<style type="text/css">
.b {
color: red;
text-align: center;
margin-top: 100px;
}
th {
padding: 10px;
}
.td {
border-left: 1px solid #E0E0E0;
border-top: 1px solid #E0E0E0;
padding: 10px;
color: Brown;
text-align: center;
}
.table {
border-bottom: 1px solid #E0E0E0;
border-right: 1px solid #E0E0E0;
width: 80%;
}
</style>
</head>
<body>
<div style="width:800px;margin:0px auto;border:1px solid Gray;height:1000px;">
<!--用于呈现要显示的数据的div-->
<div id="content" style="height:auto;">
<!--<select id="sel"></select>-->
</div>
<!--用于呈现分页控件的Div-->
<div id="pager">
</div>
<script type="text/javascript">
var totalRecord = 0;
var xmlHttpRequest = new XMLHttpRequest();
xmlHttpRequest.open("get", "../ashx文件/GetRecordCount.ashx", true);
xmlHttpRequest.onreadystatechange = function () {
if (xmlHttpRequest.readyState == 4 && xmlHttpRequest.status == "200") {
totalRecord = parseInt(xmlHttpRequest.responseText, 10);
InitializePageControl(10, totalRecord, function () {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("get", "../aspx页面/GetProduct.aspx?pageIndex=" + (this.pageIndex) + "&pageSize=" + (this.pageSize), true);
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == "200") {
var content = document.getElementById("content");
content.innerHTML = "";
content.innerHTML = xmlHttp.responseText;
}
}
xmlHttp.send(null);
}, document.getElementById("pager"));
}
}
xmlHttpRequest.send(null);
</script>
</div>
</body>
</html>
返回数据的页面:GetProduct.aspx页面
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GetProduct.aspx.cs" Inherits="开源代码.aspx页面.GetProduct" %>
<asp:repeater id="Repeater1" runat="server">
<HeaderTemplate>
<table class="table">
<tr>
<th>编号</th>
<th>姓名</th>
<th>产品编号</th>
<th>颜色</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="td"><%#Eval("ProductID") %></td>
<td class="td"><%#Eval("Name") %></td>
<td class="td"><%#Eval("ProductNumber") %></td>
<td class="td"><%#Eval("Color") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:repeater>
GetProduct.aspx.cs: using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace 开源代码.aspx页面
{
public partial class GetProduct : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Bind();
}
}
private void Bind()
{
string pageIndex = Request.QueryString["pageIndex"];
int pageSize = int.Parse(Request.QueryString["pageSize"]);
if (!string.IsNullOrEmpty(pageIndex))
{
int p = int.Parse(pageIndex);
using (SqlConnection conn = new SqlConnection("Data Source=chenxin-pc;Initial Catalog=AdventureWorks;Integrated Security=True"))
{
using (SqlCommand comm = conn.CreateCommand())
{
try
{
comm.CommandText = "with tmp as (select Row_Number() over(order by ProductID) RowIndex,* from Production.Product) select * from tmp where RowIndex between " + ((p - ) * pageSize) + " and " + (p * pageSize);
SqlDataAdapter adapter = new SqlDataAdapter(comm);
DataTable dt = new DataTable();
adapter.Fill(dt);
this.Repeater1.DataSource = dt;
this.Repeater1.DataBind();
}
catch (Exception ex)
{
Response.Write("服务器内部异常!");
}
}
}
}
else
{
Response.Write("请求的页错误!");
}
}
}
}
最后:Page.js代码如下
//用于初始化页面,调用该方法,使得第一次进入页面时加载第一页数据,并且初始化分页控件。
//pageSize:每页要显示几条记录。
//totalRecord:总共有多少条记录。
//clickFunction:点击分页按钮时要执行的函数。
//containers:一个Dom对象,表示要将分页控件呈现在哪一个元素中。
function InitializePageControl(pageSize, totalRecord, clickFunction, container) {
this.pageIndex = 1;
this.pageSize = pageSize;
clickFunction.call(this);
PageControl(1, pageSize, totalRecord, clickFunction, container);
}
//根据参数来创建一个超链接
function createAnchor(params) {
var a = document.createElement("a");
for (var attr in params) {
a[attr] = params[attr];
}
return a;
}
//pageIndex:当前要显示的是第几页。
//pageSize:每页要显示几条记录。
//totalRecord:总共有多少条记录。
//clickFunction:点击分页按钮时要执行的函数。
//containers:一个Dom对象,表示要将分页控件呈现在哪一个元素中。
function PageControl(pageIndex, pageSize, totalRecord, clickFunction, container) {
container.innerHTML = "";
if (totalRecord <= 0) {
return false;
}
var divContainer = document.createElement("div");
divContainer.className = "divContainer";
//函数func用于用户点击每一个分页按钮时,PageControl内部要处理的函数。
var func = function () {
//当前这个this是指被点击的分页按钮中的某个超链接对象。
this.pageSize = pageSize;
clickFunction.call(this);
PageControl(this.pageIndex, pageSize, totalRecord, clickFunction, container);
};
//求出总共多少页
var pageCount = Math.ceil(totalRecord / pageSize);
//上一页的超链接 只有总页数大于2页,并且当前显示的页不是第一页的时候才显示上一页
if (pageCount > 2 && pageIndex != 1) {
var previousPage = createAnchor(
{
"id": "previousPage",
"href": "#",
"className": "a",
"innerHTML": "上一页",
"onclick": func,
"pageIndex": pageIndex - 1
}
);
divContainer.appendChild(previousPage);
}
var params =
{
"href": "#",
"className": "a",
"onclick": func
}
//如果总页数大于8页,则要出现...的形式。
if (pageCount > 8) {
var firstPage = createAnchor({ "href": "#", "className": "a", "innerHTML": 1, "pageIndex": 1, "onclick": func });
var lastPage = createAnchor({ "href": "#", "className": "a", "innerHTML": pageCount, "pageIndex": pageCount, "onclick": func });
if (pageIndex > 4 && pageIndex + 4 <= pageCount) {
divContainer.appendChild(firstPage);
var a = createAnchor({ "innerHTML": "..." });
divContainer.appendChild(a);
for (var i = pageIndex - 2; i <= pageIndex + 2; i++) {
params.className = "a";
params.innerHTML = i.toString();
params.pageIndex = i;
if (i == pageIndex) {
params.className += " current";
}
a = createAnchor(params);
divContainer.appendChild(a);
}
a = createAnchor({ "innerHTML": "..." });
divContainer.appendChild(a);
divContainer.appendChild(lastPage);
}//当前要显示的页数<=4页
else if (pageIndex <= 4) {
for (var i = 1; i <= 6; i++) {
params.className = "a";
params.innerHTML = i.toString();
params.pageIndex = i;
if (i == pageIndex) {
params.className += " current";
}
a = createAnchor(params);
divContainer.appendChild(a);
}
a = createAnchor({ "innerHTML": "..." });
divContainer.appendChild(a);
divContainer.appendChild(lastPage);
}//当前要显示的是最后一页。
else {
divContainer.appendChild(firstPage);
a = createAnchor({ "innerHTML": "...", "className": "a" });
divContainer.appendChild(a);
for (var i = pageCount - 5; i <= pageCount; i++) {
params.className = "a";
params.innerHTML = i.toString();
params.pageIndex = i;
if (i == pageIndex) {
params.className += " current";//不要漏了current前面的空格哦
}
a = createAnchor(params);
divContainer.appendChild(a);
}
}
}//总页数<=8页,那么就直接显示所有的页数
else {
for (var i = 1; i <= pageCount; i++) {
params.className = "a";
params.innerHTML = i.toString();
params.pageIndex = i;
if (i == pageIndex) {
params.className += " current";
}
a = createAnchor(params);
divContainer.appendChild(a);
}
}
//之用总页数大于2页,并且当前显示的页<总页数的时候才显示下一页
if (pageCount >= 2 && pageIndex < pageCount) {
var nextPage = createAnchor(
{
"id": "nextPage",
"href": "#",
"className": "a",
"innerHTML": "下一页",
"onclick": func,
"pageIndex": (pageIndex + 1)
}
);
divContainer.appendChild(nextPage);
}
var span = document.createElement("span");
span.textContent = "转到";
span.className = "span";
divContainer.appendChild(span);
var input = document.createElement("input");
input.type = "text";
input.value = pageIndex.toString();
input.id = "txtPageIndex";
input.className = "input";
divContainer.appendChild(input);
span = document.createElement("span");
span.innerHTML = "页";
span.className = "span";
divContainer.appendChild(span);
var go = document.createElement("input");
go.type = "button";
go.className = "go";
go.value = "Go";
go.onclick = function () {
var txtPageIndex = document.getElementById("txtPageIndex");
try {
//alert("value" in txtPageIndex);
var pageIndex = parseInt(txtPageIndex.value, 10);
if (pageIndex < 1 || pageIndex > pageCount) {
alert("页数的合法范围: 1-" + pageCount);
}
else if (isNaN(pageIndex)) {
alert("页数必须为数字!");
}
else {
//这里面的this是指input,但是因为input这个东西并没有pageIndex属性,所以我们必须给其添加进去
this.pageIndex = pageIndex;
this.pageSize = pageSize;
clickFunction.call(this);
PageControl(pageIndex, pageSize, totalRecord, clickFunction, container);
}
}
catch (error) {
alert("描述:" + error.description + " 详细信息: " + error.stack + error.message);
}
}
divContainer.appendChild(go);
container.appendChild(divContainer);
}
自己动手用Javascript写一个无刷新分页控件的更多相关文章
- 小白写的一个ASP.NET分页控件,仅供娱乐
无聊,第一次写博客,自己动手写了一个分页控件.由于我是新手,有很多地方写得不够好,希望各位大牛多多指正.哈哈哈 /// <summary> /// 分页控件 /// </summar ...
- JavaScript封装一个实用的select控件
最近一直把精力放在项目上面,导致忽略的一些底层的东西.以前就一直觉得原有的select控件很丑,正好周末有时间,试着做了一个简单封装,实现了它的基本功能.我总结了一下,大概分为三个部分: 1.对显示样 ...
- 对自写的Asp.Net分页控件的应用方式(异步无刷新分页)
前台代码 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" co ...
- asp.net 分页-自己写分页控件
去年就发表过asp.net 分页-利用后台直接生成html分页 ,那种方法只是单纯的实现了分页,基本不能使用,那时就想写个自己的分页控件,无奈能力有限.最近有点时间了,就自己做出了这个分页控件.我承认 ...
- uinty3d使用ugui封装一个分页控件
我们在显示数据时有的数据比较多,手机内存有限,我们不可能分配很多的控件来显示这些数据,分页是一个不错的选择.比如玩家交易行.我们现在封装一个自己简单的分页控件来显示玩家交易行. 分页控件的原理其实很简 ...
- 用javascript写一个前端等待控件
前端等待控件有啥新奇的?什么jquery啦,第三方控件啦,好多好多,信手拈来. 因为项目使用了bootstrap的原因,不想轻易使用第三方,怕不兼容.自己写一个. 技术点包括动态加载CSS,javas ...
- PHP + JavaScript + Ajax 实现无刷新页面加载效果
数据源工厂 Json生成方式1 Json生成方式2 数据搬运工 数据加工师 转换类型 加工展示 结果展示 初始页面 点击按钮之后 总结 今天这个实验的思路就是实现一个无刷新的页面加载效果.具体的思路是 ...
- JavaScript实现页面无刷新让时间走动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 扩展GridView实现的一个自定义无刷新分页,排序,支持多种数据源的控件TwfGridView
最近项目View层越来越趋向于无刷新化,特别是数据展示方面,还要对Linq有很好的支持.在WebFrom模式的开发中,GridView是一个功能很强大,很常用的控件,但是他也不是完美的,没有自带的无刷 ...
随机推荐
- Arch linux安装
安装archlinux可参考: http://blog.sina.com.cn/s/blog_69e5d8400101bqlj.html http://www.cnblogs.com/mad/p/32 ...
- Mysql规范和使用注意点(转)
命名规范: 1表名,字段名,索引名称使用小写字母,数字采用下划线进行分割 2.表名采用模块名3个缩小字符 '前缀'之后顺序为表明 3.表名,字段名不超过32个字符 4.存储尸体数据的表,名称使用名词, ...
- 对 Azure Backup 的常见配置问题进行故障排除
Giridhar Mosay云 + Enterprise 项目经理 这篇博客文章有助于解决 Microsoft云备份解决方案(即 Azure Backup)的常见配置问题.客户通常会在安装或注册 ...
- JS模块化规范CommonJS,AMD,CMD
模块化是软件系统的属性,这个系统被分解为一组高内聚,低耦合的模块.理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过直接加载被人已经写好模块进行使用即可.一个模块化系统所必须的 ...
- Go Hello World!
有些事应该坚持去做 当你半途而废的时候意味着你又要重新开始.那么 Golang Hello world! Java Android 新手 学习 Golang First Day ! go 语言下载: ...
- dev combobox edit 怎么设置让选项清空
dev combobox edit 怎么设置让选项清空 功能需求: 点击combobox edit1的选项A 使得 combobox edit2出现选项a: 然后再点击combobox edit1的选 ...
- 利用Testng注释实现多线程并发测试
Testng 是一款非常优秀的测试框架,真正从测试角度出发,为测试所想.在测试过程中我们经常会遇到对某一个场景做并发请求,主要想了解该程序在并发时是否会有异常或者没考虑到的其他情况,这时往往不是要做性 ...
- Oracle的dmp文件的导入
项目开始拿到了dmp文件,数据库用的是10g的,但是尽然没导成功,后来想可能导出的时候用11导出的,决定试一下. 正好自己的机器是11的客户端,结果不识别imp命令,到安装目录下的bin文件夹下看尽然 ...
- IIS ASP.NETWEB站点部署时遇到的问题记录
最近由于工作的需要,需要自己部署一些ASP.NET站点,但中间出现了一点小小的问题. 由于自己才疏学浅,此问题折腾了我将近一个小时,最后还是百度出了解决这个问题的方法,先记录如下,仅供自己记忆用. 我 ...
- c++学习_1
最近重新捧起了<Effective c++>,其中味道又有不同,这里记录之... 这篇文章记录一下public继承的知识点... (1)public继承的意义 该继承方式是代表is-a(是 ...