layui-laypage模块代码详解
/** layui-v2.4.0 MIT License By https://www.layui.com */
;
layui.define(function(e) {
"use strict";
var a = document,
t = "getElementById",
n = "getElementsByTagName",
i = "laypage",
r = "layui-disabled",
u = function(e) {
var a = this;
// 实例化的时候调用了render方法,layui.laypage不存在,即接口还未对外exports时,index为0
console.log("初次索引:%c" + s.index, "color: red;");
// u是一个构造函数,此处的this将为u实例化后的实例。
// 并且索引在每次render之后增一。
// 并render,!0代表初次render。
a.config = e || {}, a.config.index = ++s.index, a.render(!0)
};
u.prototype.type = function() {
var e = this.config;
console.log("判断分页容器元素是否为对象:%c" + ("object" == typeof e.elem ? 'yes' : 'no'), 'color: blue;');
if ("object" == typeof e.elem) {
console.log("分页容器元素:", e.elem);
// document.getElementById的length是undefin,而jquery的是数值。
return void 0 === e.elem.length ? 2 : 3
} else {
console.log("分页容器元素:%c" + e.elem, "color: blue;");
}
}, u.prototype.view = function() {
var e = this,
a = e.config,
// 判断是否传入了groups,是则对其逻辑或运算,目的转为数字,否则赋默认值5
t = a.groups = "groups" in a ? 0 | a.groups : 5;
// layout 如果已赋值且为对象,使用它,否则为默认["prev", "page", "next"], 其他配置参数也进行逻辑或运算,保证为数字或有默认值
// 逻辑或还能向上取整,3.4214 | 1,对groups进行处理,负数或者大于页码数
a.layout = "object" == typeof a.layout ? a.layout : ["prev", "page", "next"], a.count = 0 | a.count, a.curr = 0 | a.curr || 1, a.limits = "object" == typeof a.limits ? a.limits : [10, 20, 30, 40, 50], a.limit = 0 | a.limit || 10, a.pages = Math.ceil(a.count / a.limit) || 1, a.curr > a.pages && (a.curr = a.pages), t < 0 ? t = 1 : t > a.pages && (t = a.pages), a.prev = "prev" in a ? a.prev : "上一页", a.next = "next" in a ? a.next : "下一页";
var n = a.pages > t ? Math.ceil((a.curr + (t > 1 ? 1 : 0)) / (t > 0 ? t : 1)) : 1,
i = {
prev: function() {
return a.prev ? '<a href="javascript:;" class="layui-laypage-prev' + (1 == a.curr ? " " + r : "") + '" data-page="' + (a.curr - 1) + '">' + a.prev + "</a>" : ""
}(),
page: function() {
var e = [];
if (a.count < 1) return "";
n > 1 && a.first !== !1 && 0 !== t && e.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="首页">' + (a.first || 1) + "</a>");
var i = Math.floor((t - 1) / 2),
r = n > 1 ? a.curr - i : 1,
u = n > 1 ?
function() {
var e = a.curr + (t - i - 1);
return e > a.pages ? a.pages : e
}() : t;
for (u - r < t - 1 && (r = u - t + 1), a.first !== !1 && r > 2 && e.push('<span class="layui-laypage-spr">…</span>'); r <= u; r++) r === a.curr ? e.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" ' + (/^#/.test(a.theme) ? 'style="">+ a.theme + ';"' : "") + "></em><em>" + r + "</em></span>") : e.push('<a href="javascript:;" data-page="' + r + '">' + r + "</a>");
return a.pages > t && a.pages > u && a.last !== !1 && (u + 1 < a.pages && e.push('<span class="layui-laypage-spr">…</span>'), 0 !== t && e.push('<a href="javascript:;" class="layui-laypage-last" title="尾页" data-page="' + a.pages + '">' + (a.last || a.pages) + "</a>")), e.join("")
}(),
next: function() {
return a.next ? '<a href="javascript:;" class="layui-laypage-next' + (a.curr == a.pages ? " " + r : "") + '" data-page="' + (a.curr + 1) + '">' + a.next + "</a>" : ""
}(),
count: '<span class="layui-laypage-count">共 ' + a.count + " 条</span>",
limit: function() {
var e = ['<span class="layui-laypage-limits"><select lay-ignore>'];
return layui.each(a.limits, function(t, n) {
e.push('<option value="' + n + '"' + (n === a.limit ? "selected" : "") + ">" + n + " 条/页</option>")
}), e.join("") + "</select></span>"
}(),
refresh: ['<a href="javascript:;" data-page="' + a.curr + '" class="layui-laypage-refresh">', '<i class="layui-icon layui-icon-refresh"></i>', "</a>"].join(""),
skip: function() {
return ['<span class="layui-laypage-skip">到第', '<input type="text" min="1" value="' + a.curr + '" class="layui-input">', '页<button type="button" class="layui-laypage-btn">确定</button>', "</span>"].join("")
}()
};
return ['<div class="layui-box layui-laypage layui-laypage-' + (a.theme ? /^#/.test(a.theme) ? "molv" : a.theme : "default") + '" id="layui-laypage-' + a.index + '">', function() {
var e = [];
return layui.each(a.layout, function(a, t) {
i[t] && e.push(i[t])
}), e.join("")
}(), "</div>"].join("")
}, u.prototype.jump = function(e, a) {
// e是配置或获取到的page元素
console.log("跳转后传入渲染元素:", e);
// render之后执行jump,做的事儿有:
// 1. 初始化则获取输入框值,渲染翻页。
// 2. 对所有a元素进行事件绑定。
// 3. select的事件绑定。
// 4. button的事件绑定。
if (e) {
var t = this,
i = t.config,
r = e.children,
// 点击按钮,即输入后的确认按钮
u = e[n]("button")[0],
// 输入框
l = e[n]("input")[0],
// 下拉菜单
p = e[n]("select")[0],
c = function() {
// 替换掉输入框中非数字部分,确保为数字。
var e = 0 | l.value.replace(/\s|\D/g, "");
// 将curr赋值,并render,即跳转后再次render
// 此处render是实例化对象上的render
// 即点击确认按钮/或初次加载后重新渲染page
e && (i.curr = e, t.render())
};
// 如果a为true,进行render,即标示了input,执行到此
if (a) return c();
// 循环给a元素加第点击事件。
for (var o = 0, y = r.length; o < y; o++)"a" === r[o].nodeName.toLowerCase() && s.on(r[o], "click", function() {
// 获取到页码数,点击的当前页码页码数赋值给配置对象的curr,指示当前所在页码,并重渲染。
var e = 0 | this.getAttribute("data-page");
// 当前页码数小于1或者大于总页码数,则不执行赋值和重渲染。
// 只有既不小于1又不大于总页码数,才赋值和重新渲染。
e < 1 || e > i.pages || (i.curr = e, t.render())
});
// select事件
p && s.on(p, "change", function() {
var e = this.value;
// 当前页码*所选值如果大于总数,则当前页码赋值为总页码/每页显示数的乡下取值。
// 然后重新渲染。
i.curr * e > i.count && (i.curr = Math.ceil(i.count / e)), i.limit = e, t.render()
}),
// 输入后的button确认事件
u && s.on(u, "click", function() {
c()
})
}
}, u.prototype.skip = function(e) {
// e为传入的分页元素对象。
if (e) {
var a = this,
t = e[n]("input")[0];
// chrome下会支持回调传入参数。
t && s.on(t, "keyup", function(t) {
console.log("keyup传入参数:", t);
// keyup的调用对象是t
var n = this.value,
i = t.keyCode;
// 上下左右键,或者输入框值为非数字,则将非数字替换为空
// 如果为确认,执行jump方法,且传入真。。
/^(37|38|39|40)$/.test(i) || (/\D+/.test(n) && (this.value = n.replace(/\D/, "")), 13 === i && a.jump(e, !0))
})
}
}, // 当前render在实例化期间被调用,在s对象中render则成为实例化对象。
u.prototype.render = function(e) {
var n = this,
// 传入的配置对象
i = n.config,
// 获取类型
r = n.type(),
// 生成view
u = n.view();
console.log("判断传入类型:%c" + r, "color: blue;");
// console.log("render获取到的配置:", i);
// 判断是原生js对象还是jquery对象,否则就调用document上的getElementById获取dom元素,
// 将生成的视图赋值给它,跳转回调存在则调用它,也即在render的时候就已经实施了对jump的调用。因此有初次调用一说。
2 === r ? i.elem && (i.elem.innerHTML = u) : 3 === r ? i.elem.html(u) : a[t](i.elem) && (a[t](i.elem).innerHTML = u),
// 此处调用意欲何为?此处jump是用户传入的回调函数,e标示是否第一次,第一次render的时候e是!0,即真
console.log("是否第一次:", e ? '是' : '否'),
i.jump && i.jump(i, e);
// i.index是不断累加的。下面的jump是构造函数上的jump
// 在view方法中以下元素已经被渲染出来了。
var s = a[t]("layui-laypage-" + i.index);
// 执行jump方法并且追加hash
n.jump(s), i.hash && !e && (location.hash = "!" + i.hash + "=" + i.curr), n.skip(s)
};
// e 为传入render的配置对象
// u 为
// function(e) {
// var a = this;
// a.config = e || {}, a.config.index = ++s.index, a.render(!0)
// };
// render 创建了一个实例,返回了索引。
var s = {
render: function(e) {
var a = new u(e);
console.log("laypage原始索引:%c" + s.index, "color: red;");
console.log("laypage配置索引:%c" + a.config.index, "color: red;");
// 返回的index已经是增1以后的。
return a.index
},
index: layui.laypage ? layui.laypage.index + 1e4 : 0,
on: function(e, a, t) {
// e是dom元素对象,a是事件名,t是回调
return e.attachEvent ? e.attachEvent("on" + a, function(a) {
// 此处a是事件对象, 两个的区别是:ie下支持e.srcElement,ff支持e.target。
// 指向触发事件的元素
a.target = a.srcElement, t.call(e, a)
// 禁止冒泡
}) : e.addEventListener(a, t, !1), this
}
};
e(i, s); /**
* 初次进入页面
* 调用:
* laypage.render({
elem: document.getElementById('laypage'), // 'laypage', $('#laypage'), document.getElementById('laypage');
count: count,
limit: limit,
limits: [5, 10, 20, 30, 50],
curr: page,
groups: 5,
prev: '上一页',
next: '下一页',
first: '首页',
last: '尾页',
layout: ['prev', 'page', 'next', 'first', 'last', 'limit', 'refresh', 'skip', 'count'],
theme: '#1E9FFF',
hash: 'curr',
jump: function (obj, first) {
console.log("jump后的配置:", obj);
if (!first) {
pageTurn(obj.curr, obj.limit);
}
}
})
* 即s对象上的render方法
* 实例化函数u,并将配置作为参数传递给u。
* 将配置对象赋值给是实例化对象。
* 给该配置对象设置索引,为s对象上的index加1。
* exports向外暴露的接口laypage在use或者作为依赖引入的时候,进入内存,初始化index,为0。
* 执行后面扩展到构造函数u上的方法render,传入参数!0,即真,表示第一次。
* 执行原型上的type方法,根据传入配置对象的elem来决定类型,2(原生dom对象),3(jquery对象),undefined(字符串)。
* 构造view html。
* 根据上面的类型赋值给elem元素html。
* 如果用户设置了jump回调,第一次不执行,传入配置对象及是否为第一次,此时为真,毫无疑问。
* 用原生js方法取到当前page元素。
* 执行render里的jump方法。
* 如果该元素存在。
* 获取到该元素的子元素button,input和select。
* 如果参数a为真,仅执行内部函数c,但此时为undefined,不执行c函数。执行c函数的情况是在skip中按下了enter键之后才会执行,前提条件是按下了上下左右方向键或者非数字,执行了input输入框非数字过滤之后,再按下enter键,渲染page。
* 对a元素进行循环绑定click事件,其中回调是获取到a上的data-page页码,比对是否大于总页码或者小于1,对配置对象的curr重新赋值,并执行render。render不传参,因此会执行用户回调。table会重新渲染,page容器的id也会随之而变。
* 对select进行事件绑定,计算curr值及limit值,配置对象发生改变,然后执行无参数render,自然table会被重新渲染,执行用户回调。
* button确认点击事件同理。
* 然后render方法中改变hash值。
* render中执行skip函数,传入page元素。
* 如果page为真,获取到input元素。
* 给他绑定keyup事件,目的是检测按下了上下左右方向键或者非数字,执行input输入框非数字过滤之后,再按下enter键,执行jump。
* 此时jump第二个参数为真。不在jump里执行button,a及seelct的绑定。会执行内部函数c,render的参数为空,即非第一次调用。
* render会调用用户回调,并再执行jump,此时jump的第二个参数为空。执行select,a,button的事件绑定及在skip函数里执行input的keyup事件绑定。
* 结束
*
* 模拟点击页码3
* 此时初次render已经结束。
* 点击页码3发生,即执行了a上绑定的click事件。
* 此时获取到页码3。
* 判断页码是否小于1大于总页码,不是,赋值给配置对象的curr,执行render,不传参数。
* this赋值给n。
* 配置对象赋值给i。
* 获取到type值为undefined,假设配置中写的是字符串。
* 生成view。
* 将view结果赋值给指定id元素。
* 判断是否设置了用户回调。
* 是,执行回调。此时render传入参数为空,即假。回调中如果设置了if(!first){}则会执行。
* 当前系统中会重新渲染table。
* 获取当前page容器元素。因为点击过后,执行了用户回调,而用户回调中再次调用了laypage.render,所以index会增1。
* 执行jump函数,传入此容器元素。
* 此时jump的第二个参数为假,因此在这一步就执行了button,select及a元素的事件绑定。
* 然后hash值赋值。
* 执行skip,为input绑定keyup事件。
* keyup事件中检测输入是否为上下左右键以及非数字,则input中值自动过滤掉这些字符,如果按下enter,则执行jump。
* 因为传入第二个参数为真,因此会先执行render,因为在keyup中可能输入的数字合法,必须要重新render。
* 结束。
*/
});
layui-laypage模块代码详解的更多相关文章
- opencart 模块开发详解
opencart 模块开发详解 由 xiekanxiyang » 2013年 7月 11日 10:17 pm opencart 将页面分成若干模块, 每个模块可以有多个实例(可能这样说不是很恰当) 每 ...
- AngularJS模块的详解
AngularJS模块的详解 在讲angularjs的模块之前,我们先介绍一下angular的一些知识点: AngularJS是纯客户端技术,完全用Javascript编写的.它使用的是网页开发的常规 ...
- [转帖]Nginx rewrite模块深入浅出详解
Nginx rewrite模块深入浅出详解 https://www.cnblogs.com/beyang/p/7832460.html rewrite模块(ngx_http_rewrite_modul ...
- Github-jcjohnson/torch-rnn代码详解
Github-jcjohnson/torch-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2016-3- ...
- DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解
本文介绍多层感知机算法,特别是详细解读其代码实现,基于python theano,代码来自:Multilayer Perceptron,如果你想详细了解多层感知机算法,可以参考:UFLDL教程,或者参 ...
- springboot扫描自定义的servlet和filter代码详解_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 这几天使用spring boot编写公司一个应用,在编写了一个filter,用于指定编码的filter,如下: /** ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- ASP.NET MVC 5 学习教程:生成的代码详解
原文 ASP.NET MVC 5 学习教程:生成的代码详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...
- Github-karpathy/char-rnn代码详解
Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2016-1-10 ...
随机推荐
- JS 随机整数
<script> function GetRandomNum(Min,Max){ var Range = Max - Min; var Rand = Math.random() ...
- (暂时弃坑)(半成品)ACM数论之旅18---反演定理 第二回 Mobius反演(莫比乌斯反演)((づ ̄3 ̄)づ天才第一步,雀。。。。)
莫比乌斯反演也是反演定理的一种 既然我们已经学了二项式反演定理 那莫比乌斯反演定理与二项式反演定理一样,不求甚解,只求会用 莫比乌斯反演长下面这个样子(=・ω・=) d|n,表示n能够整除d,也就是d ...
- window.location.hash 使用
[转]http://www.cnblogs.com/nifengs/p/5104763.html location是javascript里边管理地址栏的内置对象,比如location.href就管理页 ...
- Python 的 “Magic” 方法
在以前的文章中,我聊过了Python的 __getitem__ 和 __setitem__ 方法.这些方法被称为“魔法”方法.特殊方法或者dunger方法(译者:国内书籍用“魔法”一词较多).那么,什 ...
- Timing wheel心跳机制
在web服务中,断开空闲连接是一种减少资源浪费的一种手段,由此就有了心跳机制来判断一个连接是否空闲. 一种简单粗暴的方式: 1. 服务端每个连接保存一个最后一次操作的时间戳,每次这个连接对应fd可读时 ...
- [洛谷P4723]【模板】线性递推
题目大意:求一个满足$k$阶齐次线性递推数列$a_i$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n-i}$ 题解:线性齐次递推,先见洛谷题解, ...
- 【BZOJ1072】排列(搜索)
[BZOJ1072]排列(搜索) 题面 BZOJ 洛谷 题解 算下复杂度,如果用\(next\_permutation\) 那就是\(10!\times 10\times 15\),复杂度不太对 那好 ...
- 【poj3420】 Quad Tiling
http://poj.org/problem?id=3420 (题目链接) 题意 给出$n*m$的网格,用$1*2$的方块覆盖有多少种方案. Solution 数据很大,不能直接搞了,我们矩乘一下.0 ...
- Android Studio中多项目共享Library
FAQ: as的projectA中有一个commonLib的源码库模块,projectB要调用其中的commonLib, 这个有没有方案?不用手动拷贝aar的 方案1. 采用gradle配置参数方 ...
- sqoop 补充
1.用 sqoop 将MySQL中的数据导入hbase中 sqoop import \--connect jdbc:mysql://***.***.*.***:3306/mysql \--hbase- ...