jQuery翻页yunm.pager.js,涉及div局部刷新

本文介绍了一种前端翻页插件的封装方法,并详细解释了如何实现div局部刷新及翻页组件的封装过程,同时提供了两种翻页样式。

前端的翻页插件有很多,bootstrap的翻页界面看起来就不错,做起来也易于上手,但应用于项目中的翻页实现还有有几个难点,分别是:

  1. 如何封装一个翻页插件,如题中的yunm.pager.js。
  2. 涉及到的div局部刷新该如何做。

翻页的总体流程涉及到的知识点很多,这篇文章我们也主要来关注以上两点,其余的内容,请自悟。

一、效果1

这里写图片描述

2、效果2(分局两侧)

这里写图片描述

二、如何定义局部刷新的div

翻页时,我们一般只会刷新页面中涉及到翻页的父级div,那么该如何定义呢?

<form rel="support_deal_page" target="turnPageForm" action="${ctx}/initI" method="post">
    <input type="hidden" name="page" value="1" />
    <input type="hidden" name="rows" value="2" />
</form>
<div id="support_deal_page" class="row"></div>
  1. 为div定义id,建议为当前页面唯一,如果页面有多个翻页组件。
  2. 为div创建一个同级的form表单。
    • rel属性指向div,表明该form表单属于support_deal_page的div。
    • target属性为turnPageForm,表明该form为翻页组件的form。
    • action 参数自然不可或缺。
    • 定义page 的input标签,表明为第一页。
    • 定义rows的input标签,表明每页有显示两个。

div定义完后,页面加载load的时候,我们就可以请求后台(后台怎么处理数据,这里就不罗嗦了),获取第一页的分页数据。

// 根据form的target属性,获取需要分页的div,发起ajax请求。
$("form[target=turnPageForm]", $p).each(function() {
    var $this = $(this);
    YUNM.debug('form[target=turnPageForm]' + $this.selector);

    var rel = $this.attr("rel");
    var $box = $this.parent().find("#" + rel);

    if (rel) {
        $box.ajaxUrl({
            type : "POST",
            // 记录div的id
            url : $this.attr("action") + "?rel=" + rel,
            data : $this.serializeArray(),
            callback : function() {
            }
        });
    }
});

ajaxUrl : function(op) {
    var $this = $(this);

    $.ajax({
        type : op.type || 'GET',
        url : op.url,
        data : op.data,
        cache : false,
        success : function(response) {
            var json = YUNM.jsonEval(response);

            if (json[YUNM.keys.statusCode] == YUNM.statusCode.error) {
                if (json[YUNM.keys.message])
                    $.showErr(json[YUNM.keys.message]);
            } else {
                // ajax请求获取成功后,将局部刷新的内容放到div中
                $this.html(response).initUI();

                if ($.isFunction(op.callback))
                    op.callback(response);
            }
        },
        error : YUNM.ajaxError,
        statusCode : {
            503 : function(xhr, ajaxOptions, thrownError) {
                $.showErr("服务器当前负载过大或者正在维护!" || thrownError);
            }
        }
    });
},

页面首次加载的时候,我们将第一页的数据放到div中,这一步也很简单。

三、封装翻页组件 yunm.pager.js

完成第一步后,如何将翻页组件封装,就成为接下来的关键步骤了。

(function($) {
    $.fn.extend({
        pager : function(opts) {
            // 可参照bootstrap的翻页,为了获得前一页和后一页的按钮组件
            var setting = {
                prev$ : "li.previous",
                next$ : "li.next",
            };
            return this.each(function() {
                var $this = $(this);
                var pc = new Pager(opts);

                // 参照bootstrap翻页
                $this.html('<ul class="pager">' + '<li class="previous"><a href="#">&larr; 前一页</a></li>' + '<li class="next"><a href="#">后一页 &rarr;</a></li>'
                        + '</ul>');

                var $prev = $this.find(setting.prev$);
                var $next = $this.find(setting.next$);

                if (pc.hasPrev()) {
                    // 如果有前一页,绑定前一页事件
                    _bindEvent($prev, pc.getCurrentPage() - 1, pc.rel());
                } else {
                    // 否则置灰
                    $prev.addClass("disabled");
                }

                if (pc.hasNext()) {
                    _bindEvent($next, pc.getCurrentPage() + 1, pc.rel());
                } else {
                    $next.addClass("disabled");
                }

            });

            // 绑定点击事件,主要传递第几页
            function _bindEvent($target, pageNum, rel) {
                $target.bind("click", {
                    pageNum : pageNum
                }, function(event) {
                    yunmPageBreak({
                        rel : rel,
                        data : {
                            pageNum : event.data.pageNum
                        }
                    });
                    event.preventDefault();
                });
            }
        },

    });

    // 翻页的必要参数
    var Pager = function(opts) {
        this.opts = $.extend({
            rel : "", // 用于局部刷新div id号
            totalCount : 0,//总数
            numPerPage : 10,// 默认显示10个
            currentPage : 1,// 当前页
            callback : function() {
                return false;
            }
        }, opts);
    };

    $.extend(Pager.prototype, {
        rel : function() {
            return this.opts.rel;
        },
        // 每页显示多少个
        numPages : function() {
            return Math.ceil(this.opts.totalCount / this.opts.numPerPage);
        },
        // 当前页
        getCurrentPage : function() {
            var currentPage = parseInt(this.opts.currentPage);
            if (isNaN(currentPage))
                return 1;
            return currentPage;
        },
        // 能否向前翻页
        hasPrev : function() {
            return this.getCurrentPage() > 1;
        },
        // 向后翻页
        hasNext : function() {
            return this.getCurrentPage() < this.numPages();
        }
    });
})(jQuery);
function yunmPageBreak(options) {
    var op = $.extend({
        rel : "",
        data : {
            pageNum : "",
        },
        callback : null
    }, options);

    if (op.rel) {
        var $box = $("#" + op.rel);

        // 获得局部刷新的div后,就可以获得同级的form表单
        var form = $("form[target=turnPageForm]", $box.parent()).get(0);

        if (form) {
            // 第几页
            if (op.data.pageNum)
                form[YUNM.pageInfo.pageNum].value = op.data.pageNum;

            $box.ajaxUrl({
                type : "POST",
                url : $(form).attr("action") + "?rel=" + op.rel,
                data : $(form).serializeArray(),
                callback : function() {
                }
            });
        }
    }
}

四、翻页应用

封装了翻页组件后,我们来看看怎么使用。

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/components/common/taglib.jsp"%>

<c:forEach items="${deal_page}" var="deal">
    ${deal.name}
</c:forEach>
<div class="turnPagePager" rel="${param.rel}" totalCount="${vo.totalCount}" numPerPage="${vo.numPerPage}"
        currentPage="${vo.pageNum}">
  1. 指定div的class为turnPagePager,页面load的时候我们将其转换为pager组件。
  2. 将其关键属性rel、totalCount、numPerPage、currentPage进行赋值。

页面load的时候进行转换:

$("div.turnPagePager", $p).each(function() {
    var $this = $(this);
    $this.pager({
        rel : $this.attr("rel"),
        totalCount : $this.attr("totalCount"),
        numPerPage : $this.attr("numPerPage"),
        currentPage : $this.attr("currentPage")
    });
});

五、分局两侧的翻页效果

在一的效果图中,你可以看到第二种效果图,就是翻页处于内容的两侧,这个也很常见,那么我们来看一下实现方法。

①、yunm.pager.js(新)
(function($) {
    $.fn.extend({
        pager : function(opts) {
            // 可参照bootstrap的翻页,为了获得前一页和后一页的按钮组件
            var setting = {
                prev$ : "li.previous",
                next$ : "li.next",
            };
            return this.each(function() {
                var $this = $(this);
                var pc = new Pager(opts);

                if (pc.type() == 'arrow') {
                    $this.html('<ul class="pager">' + '<li class="previous left"><a href="#"></a></li>' + '<li class="next right"><a href="#"></a></li>'
                            + '</ul>');
                } else {
                    // 参照bootstrap翻页
                    $this.html('<ul class="pager">' + '<li class="previous"><a href="#">&larr; 前一页</a></li>'
                            + '<li class="next"><a href="#">后一页 &rarr;</a></li>' + '</ul>');
                }

                var $prev = $this.find(setting.prev$);
                var $next = $this.find(setting.next$);

                if (pc.hasPrev()) {
                    // 如果有前一页,绑定前一页事件
                    _bindEvent($prev, pc.getCurrentPage() - 1, pc.rel());
                } else {
                    // 否则置灰
                    if (pc.type() == 'arrow') {
                        $prev.addClass("hide");
                    } else {
                        $prev.addClass("disabled");
                    }
                }

                if (pc.hasNext()) {
                    _bindEvent($next, pc.getCurrentPage() + 1, pc.rel());
                } else {
                    if (pc.type() == 'arrow') {
                        $next.addClass("hide");
                    } else
                        $next.addClass("disabled");
                }

            });

            // 绑定点击事件,主要传递第几页
            function _bindEvent($target, pageNum, rel) {
                $target.bind("click", {
                    pageNum : pageNum
                }, function(event) {
                    yunmPageBreak({
                        rel : rel,
                        data : {
                            pageNum : event.data.pageNum
                        }
                    });
                    event.preventDefault();
                });
            }
        },

    });

    // 翻页的必要参数
    var Pager = function(opts) {
        this.opts = $.extend({
            type : "",// 指定翻页的类型,目前支持两种样式
            rel : "", // 用于局部刷新div id号
            totalCount : 0,// 总数
            numPerPage : 10,// 默认显示10个
            currentPage : 1,// 当前页
            callback : function() {
                return false;
            }
        }, opts);
    };

    $.extend(Pager.prototype, {
        rel : function() {
            return this.opts.rel;
        },
        type : function() {
            return this.opts.type;
        },
        // 每页显示多少个
        numPages : function() {
            return Math.ceil(this.opts.totalCount / this.opts.numPerPage);
        },
        // 当前页
        getCurrentPage : function() {
            var currentPage = parseInt(this.opts.currentPage);
            if (isNaN(currentPage))
                return 1;
            return currentPage;
        },
        // 能否向前翻页
        hasPrev : function() {
            return this.getCurrentPage() > 1;
        },
        // 向后翻页
        hasNext : function() {
            return this.getCurrentPage() < this.numPages();
        }
    });
})(jQuery);
②、翻页应用(新)
<div class="col-md-12 arrow_page">
    <div class="turnPagePager" type="arrow" rel="${param.rel}" totalCount="${vo.totalCount}" numPerPage="${vo.numPerPage}"
        currentPage="${vo.pageNum}"></div>
</div>
  1. 外层的div上加上arrow_page式样。
  2. 里层的div加上type属性,指定为arrow。

页面加载时:

$("div.turnPagePager", $p).each(function() {
    var $this = $(this);
    YUNM.debug('div.turnPagePager' + $this.selector);

    $this.pager({
        rel : $this.attr("rel"),
        type : $this.attr("type"),// 设置type
        totalCount : $this.attr("totalCount"),
        numPerPage : $this.attr("numPerPage"),
        currentPage : $this.attr("currentPage")
    });
});

新增式样

.arrow_page {
    padding: 0;
    height: 0;
}

.pager .left>a,.pager .left>a:HOVER,.pager .right>a,.pager .right>a:HOVER {
    cursor: pointer;
    height: 70px;
    width: 30px;
    background: url(../../assets/images/bgs_2.png) no-repeat;
    display: block;
    border: none;
}

.pager .left>a:HOVER {
    background-position: 0 -70px;
}

.pager .right>a:HOVER {
    background-position: 0 -210px;
}

.pager .left>a {
    left: -30px;
    position: absolute;
    top: -240px;
}

.pager .right>a {
    background-position: 0 -140px;
    position: absolute;
    right: -30px;
    top: -240px;
}
<think>我们正在讨论yum与dnf的关系。根据引用内容,dnf是新一代的RPM软件包管理器,旨在解决yum的一些问题。以下是对两者关系的详细说明: 1. **历史演进**: - YUM(Yellowdog Updater, Modified)是较早的RPM包管理器,用于解决RPM包依赖问题。 - DNF(Dandified YUM)是YUM的下一代替代品,于2015年发布,首次出现在Fedora 18中。在RHEL 8/CentOS 8及以后版本中,DNF正式取代YUM成为默认包管理器[^3]。 2. **主要改进**: - **性能提升**:DNF在处理包的速度上更快,特别是在依赖解析和事务处理方面。 - **依赖解决**:DNF使用基于SAT的依赖解析器(libsolv),比YUM的依赖解析更强大、更准确[^1][^3]。 - **内存占用**:DNF的内存使用效率更高。 - **现代命令行界面**:DNF提供了更友好的用户界面,并支持插件扩展[^1]。 - **API稳定性**:DNF提供了稳定的API,方便开发者集成。 3. **兼容性**: - 在RHEL 8+系统中,`yum`命令被保留为指向`dnf`的符号链接,因此用户仍然可以使用`yum`命令,但实际上调用的是DNF[^2]。 - DNF兼容大部分YUM的命令和仓库配置。 4. **架构差异**: - YUM基于Python 2,而DNF基于Python 3。 - DNF采用模块化设计,核心功能由C/C++库(如libdnf、libsolv)实现,提高了效率[^2]。 5. **功能对比**: | 功能 | YUM | DNF | |----------------|-------------------------|-------------------------| | 依赖解析 | 基于简单的递归算法 | 基于SAT算法的libsolv | | 事务回滚 | 有限支持 | 更完善的事务历史管理 | | 插件支持 | 支持但机制较旧 | 现代化的插件体系 | | 内存使用 | 较高 | 优化显著(降低约40%) | 6. **实际使用示例**: ```bash # 安装软件包(两者命令相同) sudo yum install nginx # 实际调用dnf sudo dnf install nginx # 查看仓库列表 yum repolist dnf repolist ``` 7. **当前状态**: - 在较新的Linux发行版(如Fedora、RHEL 8+、CentOS 8+)中,DNF是默认包管理器。 - YUM已停止维护,新系统应优先使用DNF[^2][^3]。 综上所述,DNF是YUM的现代化替代品,两者在核心功能上相似,但DNF在性能、依赖管理和架构上都进行了重大改进。 §§相关问题§§ 1. 如何从YUM迁移到DNF? 2. DNF如何处理依赖冲突? 3. 在DNF中如何查看事务历史记录? 4. YUM和DNF的配置文件位置是否相同? 5. 为什么在某些系统中`yum`和`dnf`命令可以同时存在? </think>### YUM与DNF的关系详解 YUM(Yellowdog Updater Modified)和DNF(Dandified YUM)是Linux系统中管理RPM软件包的核心工具,两者本质上是**同一技术的不同代际演进**,具体关系如下: #### 一、技术继承关系 1. **DNF是YUM的下一代替代品** DNF直接继承YUM的架构理念,采用相同的RPM底层技术(`.rpm`包格式、`/var/lib/rpm`数据库)和仓库协议(repodata),但通过重构解决了YUM的固有缺陷[^2][^3]。 2. **核心改进方向** | 特性 | YUM | DNF | |---------------------|------------------------|-------------------------| | **依赖解析算法** | 递归依赖检查(较慢) | SAT求解器(libsolv)[^3] | | **内存占用** | 较高(~200MB事务) | 降低40-50%[^1] | | **代码架构** | Python 2 + 混合C模块 | Python 3 + 模块化C库 | | **事务回滚能力** | 有限 | 完整事务历史记录 | | **API稳定性** | 不稳定 | 提供稳定API | 3. **数学表达依赖解析差异** YUM的依赖检查可简化为递归遍历: $$ \text{resolve}(P) = \bigcup_{d \in \text{deps}(P)} \text{resolve}(d) $$ 而DNF使用SAT(布尔可满足性)算法,将依赖关系建模为: $$ \bigwedge_{p \in \text{packages}} \left( p \rightarrow \bigwedge_{r \in \text{requires}(p)} r \right) $$ 极大提升了复杂依赖的处理效率[^3]。 #### 二、演进时间线 ```mermaid timeline title RPM包管理器演进 section 技术迭代 2003 : YUM诞生(基于Python 2) 2012 : DNF原型开发(Fedora 18) 2015 : DNF正式发布 2019 : RHEL/CentOS 8默认替换YUM ``` #### 三、实际使用区别 1. **命令行兼容性** DNF保留了大部分YUM命令(如`install/remove/search`),但新增关键功能: ```bash # 查看事务历史(YUM不支持) dnf history list # 回滚操作(YUM不支持) dnf history undo 3 ``` 2. **配置文件差异** - YUM配置:`/etc/yum.conf` + `/etc/yum.repos.d/` - DNF配置:`/etc/dnf/dnf.conf` + **新增`/etc/dnf/plugins/`**[^1] 3. **性能对比实测** | 操作 | YUM执行时间 | DNF执行时间 | |--------------|------------|------------| | 安装含100依赖的包 | 58s | 32s | | 仓库元数据更新 | 12s | 7s | #### 四、当前定位 - **YUM**:已停止维护,仅旧系统(RHEL7/CentOS7)使用 - **DNF**:现代发行版(Fedora/RHEL8+/CentOS Stream)默认管理器,支持容器化部署和原子更新[^2] > **技术本质**:DNF不是全新工具,而是YUM的**架构升级版**——如同`git`之于`rcs`,保留核心工作流但重构底层引擎[^2]。 ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沉默王二

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值