zoukankan      html  css  js  c++  java
  • 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 : "&#x4E0A;&#x4E00;&#x9875;", a.next = "next" in a ? a.next : "&#x4E0B;&#x4E00;&#x9875;";
    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="&#x9996;&#x9875;">' + (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">&#x2026;</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">&#x2026;</span>'), 0 !== t && e.push('<a href="javascript:;" class="layui-laypage-last" title="&#x5C3E;&#x9875;" 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">&#x5230;&#x7B2C;', '<input type="text" min="1" value="' + a.curr + '" class="layui-input">', '&#x9875;<button type="button" class="layui-laypage-btn">&#x786e;&#x5b9a;</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。
    * 结束。
    */
    });
  • 相关阅读:
    Python实现机器人聊天
    node.js使用express框架进行文件上传
    nginx让所有的http地址重定向到https
    nginx配置https
    vscode源码编译运行打包使其由英文变为中文
    阿里云配置tomcat https
    springboot打成的jar包如何在Linux上持久运行
    wordpress数据表分析
    DevExpress Components16.2.6 Source Code 重编译教程
    DataGridView绑定泛型List时,利用BindingList来实现增删查改
  • 原文地址:https://www.cnblogs.com/jiangtian/p/laypage-explanation.html
Copyright © 2011-2022 走看看