前端修炼 - Bootstrap实现分页效果

切实可行,有问题请留言 ~

简单了解

只是通过菜鸟简单了解Bootstrap 分页属性,其实因为没有任何封装耗时还是蛮多的,故此主要看下面的关键部分和后续的扩展使用

可以直接去菜鸟教程 - Bootstrap 分页简单了解一番~

关键部分

Effect
在这里插入图片描述

bootstrap-paginator.js(封装 - 分页功能)

此文件一般存放在 webapp\WEB-INF\views\common\js 目录中

bootstrap-paginator.js文件源码(直接copy)

(function($) {
    "use strict";
    /**
     * Bootstrap分页构造函数
     *
     * @param 分页的容器对象
     * @param 分页的相关配置
     *
     * */
    var BootstrapPaginator = function(element, options) {
            this.init(element, options);
        },
        old = null;

    BootstrapPaginator.prototype = {

        /**
         * 分页初始化, 把element和options作为参数
         *
         * @param element 分页的容器对象
         * @param options 分页的相关配置
         *
         * */
        init: function(element, options) {

            this.$element = $(element);

            var version = (options && options.bootstrapMajorVersion) ? options.bootstrapMajorVersion : $.fn.bootstrapPaginator.defaults.bootstrapMajorVersion,
                id = this.$element.attr("id");
            if(version === 2 && !this.$element.is("div")) {
                throw "在Bootstrap2中,必须使用div作为分页的容器";
            } else if(version > 2 && !this.$element.is("ul")) {
                throw "在Bootstrap3中,必须使用ul作为分页的容器"
            }
            this.currentPage = 1;
            this.lastPage = 1;
            this.setOptions(options);
            this.initialized = true;
        },

        /**
         * 更新分页element的属性
         *
         * @param 分页的相关配置
         * */
        setOptions: function(options) {

            this.options = $.extend({}, (this.options || $.fn.bootstrapPaginator.defaults), options);

            this.totalPages = parseInt(this.options.totalPages, 10); //设置总页数
            this.numberOfPages = parseInt(this.options.numberOfPages, 10); //设置要显示的页数

            //设置总页数后移除当前页设置,否则会导致页面异常
            if(options && typeof(options.currentPage) !== 'undefined') {

                this.setCurrentPage(options.currentPage);
            }

            this.listen();

            //呈现分页
            this.render();

            if(!this.initialized && this.lastPage !== this.currentPage) {
                this.$element.trigger("page-changed", [this.lastPage, this.currentPage]);
            }

        },

        /**
         * 设置时间监听器,如果可用的话,页面点击和切换事件是关联的
         *
         * */
        listen: function() {

            this.$element.off("page-clicked");

            this.$element.off("page-changed"); // 卸载元素事件

            if(typeof(this.options.onPageClicked) === "function") {
                this.$element.bind("page-clicked", this.options.onPageClicked);
            }

            if(typeof(this.options.onPageChanged) === "function") {
                this.$element.on("page-changed", this.options.onPageChanged);
            }

            this.$element.bind("page-clicked", this.onPageClicked);
        },

        /**
         *
         *  销毁paginator元素,首先卸载事件,然后清空里面的内容。
         *
         * */
        destroy: function() {

            this.$element.off("page-clicked");

            this.$element.off("page-changed");

            this.$element.removeData('bootstrapPaginator');

            this.$element.empty();

        },

        /**
         * 显示分页
         *
         * */
        show: function(page) {

            this.setCurrentPage(page);

            this.render();

            if(this.lastPage !== this.currentPage) {
                this.$element.trigger("page-changed", [this.lastPage, this.currentPage]);
            }
        },

        /**
         * 显示下一页
         *
         * */
        showNext: function() {
            var pages = this.getPages();

            if(pages.next) {
                this.show(pages.next);
            }

        },

        /**
         * 显示上一页
         *
         * */
        showPrevious: function() {
            var pages = this.getPages();

            if(pages.prev) {
                this.show(pages.prev);
            }

        },

        /**
         * 显示第一页
         *
         * */
        showFirst: function() {
            var pages = this.getPages();

            if(pages.first) {
                this.show(pages.first);
            }

        },

        /**
         * 显示最后一页
         *
         * */
        showLast: function() {
            var pages = this.getPages();

            if(pages.last) {
                this.show(pages.last);
            }

        },

        /**
         * 页码单击处理程序,单击页码时,将当前页更改为相应的页面,并触发监听器的pageClick事件
         *
         *
         * */
        onPageItemClicked: function(event) {

            var type = event.data.type,
                page = event.data.page;

            this.$element.trigger("page-clicked", [event, type, page]);

        },
        /**
         * 点击跳转事件
         * @param event
         */
        onPageItemJumped: function(event) {
            var type = event.data.type;
            var value = this.$element.find('input').val();
            var page = parseInt(value, 10);
            if(!isNaN(value) && page > 0 && page != this.currentPage && page <= this.totalPages) {
                this.$element.trigger("page-clicked", [event, type, page]);
            }
        },
        onPageClicked: function(event, originalEvent, type, page) {

            //显示相应页面,并在事件返回之前检查新建的页面

            var currentTarget = $(event.currentTarget);

            switch(type) {
                case "first":
                    currentTarget.bootstrapPaginator("showFirst");
                    break;
                case "prev":
                    currentTarget.bootstrapPaginator("showPrevious");
                    break;
                case "next":
                    currentTarget.bootstrapPaginator("showNext");
                    break;
                case "last":
                    currentTarget.bootstrapPaginator("showLast");
                    break;
                case "page":
                    currentTarget.bootstrapPaginator("show", page);
                    break;
                case "jump":
                    currentTarget.bootstrapPaginator("show", page);
                    break;
            }

        },

        /**
         * 根据内部属性和设置呈现分页(生成分页主函数,要修改分页的生成主要就在这里)
         *
         *
         * */
        render: function() {

            //获取容器class并将其添加到容器中
            var containerClass = this.getValueFromOption(this.options.containerClass, this.$element),
                size = this.options.size || "normal",
                alignment = this.options.alignment || "left",
                pages = this.getPages(),
                listContainer = this.options.bootstrapMajorVersion === 2 ? $("<ul></ul>") : this.$element,
                listContainerClass = this.options.bootstrapMajorVersion === 2 ? this.getValueFromOption(this.options.listContainerClass, listContainer) : null,
                first = null,
                prev = null,
                next = null,
                last = null,
                p = null,
                i = 0;

            this.$element.prop("class", "");

            this.$element.addClass("pagination");

            switch(size.toLowerCase()) {
                case "large":
                case "small":
                case "mini":
                    this.$element.addClass($.fn.bootstrapPaginator.sizeArray[this.options.bootstrapMajorVersion][size.toLowerCase()]);
                    break;
                default:
                    break;
            }

            if(this.options.bootstrapMajorVersion === 2) {
                switch(alignment.toLowerCase()) {
                    case "center":
                        this.$element.addClass("pagination-centered");
                        break;
                    case "right":
                        this.$element.addClass("pagination-right");
                        break;
                    default:
                        break;
                }
            }

            this.$element.addClass(containerClass);

            //清空最外面的容器,然后把列表添加进容器中。
            this.$element.empty();

            if(this.options.bootstrapMajorVersion === 2) {
                this.$element.append(listContainer);

                listContainer.addClass(listContainerClass);
            }

            //更新页面元素引用
            this.pageRef = [];

            if(pages.first) { //如果是第1页
                first = this.buildPageItem("first", pages.first);
                if(first) {
                    listContainer.append(first);
                }

            }

            if(pages.prev) { //如果是上一页
                prev = this.buildPageItem("prev", pages.prev);
                if(prev) {
                    listContainer.append(prev);
                }

            }

            for(i = 0; i < pages.length; i = i + 1) { //填写数字
                p = this.buildPageItem("page", pages[i]);
                if(p) {
                    listContainer.append(p);
                }
            }

            if(pages.next) { //如果是下一页
                next = this.buildPageItem("next", pages.next);
                if(next) {
                    listContainer.append(next);
                }
            }

            if(pages.last) { //如果是最后一页
                last = this.buildPageItem("last", pages.last);
                if(last) {
                    listContainer.append(last);
                }
            }
            //新加的
            var itemCustom = $("<li></li>"); //创建一个容器
            var itemHtml = "<span><input type='text' style='width: 30px;height: 20px;' value='" + this.currentPage + "'/> / " + this.totalPages + "</span>";
            itemCustom.append(itemHtml);
            listContainer.append(itemCustom);
            var itemlast = $("<li></li>"); //创建一个‘跳转’的span
            var itemTz = $("<span style='cursor: pointer;'>跳转</span>").on("click", null, {
                type: 'jump'
            }, $.proxy(this.onPageItemJumped, this)); //绑定点击事件
            itemlast.append(itemTz);
            listContainer.append(itemlast);
        },

        /**
         *
         * 根据给定的类型和页码创建page
         *
         * @param page 页码
         * @param type 类型(first, prev, page, next, last)
         *
         * @return 构造的页面元素
         * */
        buildPageItem: function(type, page) {
            var itemContainer = $("<li></li>"), //创建一个容器
                itemContent = $("<a style='cursor: pointer;'></a>"), //创建一个内容
                text = "",
                title = "",
                itemContainerClass = this.options.itemContainerClass(type, page, this.currentPage),
                itemContentClass = this.getValueFromOption(this.options.itemContentClass, type, page, this.currentPage),
                tooltipOpts = null;

            switch(type) {
                case "first":
                    itemContainerClass = "";
                    if(!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) {
                        return;
                    }
                    text = this.options.itemTexts(type, page, this.currentPage);
                    title = this.options.tooltipTitles(type, page, this.currentPage);
                    break;
                case "last":
                    itemContainerClass = "";
                    if(!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) {
                        return;
                    }
                    text = this.options.itemTexts(type, page, this.currentPage);
                    title = this.options.tooltipTitles(type, page, this.currentPage);
                    break;
                case "prev":
                    itemContainerClass = "";
                    if(!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) {
                        return;
                    }
                    text = this.options.itemTexts(type, page, this.currentPage);
                    title = this.options.tooltipTitles(type, page, this.currentPage);
                    break;
                case "next":
                    itemContainerClass = "";
                    if(!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) {
                        return;
                    }
                    text = this.options.itemTexts(type, page, this.currentPage);
                    title = this.options.tooltipTitles(type, page, this.currentPage);
                    break;
                case "page":
                    if(!this.getValueFromOption(this.options.shouldShowPage, type, page, this.currentPage)) {
                        return;
                    }
                    text = this.options.itemTexts(type, page, this.currentPage);
                    title = this.options.tooltipTitles(type, page, this.currentPage);
                    break;
            }

            itemContainer.addClass(itemContainerClass).append(itemContent);

            itemContent.addClass(itemContentClass).html(text).on("click", null, {
                type: type,
                page: page
            }, $.proxy(this.onPageItemClicked, this));

            if(this.options.pageUrl) {
                itemContent.attr("href", this.getValueFromOption(this.options.pageUrl, type, page, this.currentPage));
            }

            if(this.options.useBootstrapTooltip) {
                tooltipOpts = $.extend({}, this.options.bootstrapTooltipOptions, {
                    title: title
                });
                itemContent.tooltip(tooltipOpts);
            } else {
                itemContent.attr("title", title);
            }
            return itemContainer;
        },

        setCurrentPage: function(page) {
            if(page > this.totalPages || page < 1) { // 如果当前页码超出范围,则抛出异常

                throw "页码超出范围";

            }
            this.lastPage = this.currentPage;
            this.currentPage = parseInt(page, 10);
        },

        /**
         * 获取表示页面对象当前状态的数组。
         *
         * @return 输出具有first, prev, next, last和中间页码的对象.
         * */
        getPages: function() {
            var totalPages = this.totalPages, //通过总记录获取或计算总页数
                pageStart = (this.currentPage % this.numberOfPages === 0) ? (parseInt(this.currentPage / this.numberOfPages, 10) - 1) * this.numberOfPages + 1 : parseInt(this.currentPage / this.numberOfPages, 10) * this.numberOfPages + 1, //calculates the start page.
                output = [],
                i = 0,
                counter = 0;

            pageStart = pageStart < 1 ? 1 : pageStart; //检查页面的开始范围,看它是否小于1。

            for(i = pageStart, counter = 0; counter < this.numberOfPages && i <= totalPages; i = i + 1, counter = counter + 1) { //填写页面
                output.push(i);
            }

            output.first = 1; //在当前页面离开第一页时添加first

            if(this.currentPage > 1) { // 在当前页面离开第一页时添加prev
                output.prev = this.currentPage - 1;
            } else {
                output.prev = 1;
            }

            if(this.currentPage < totalPages) { // 当前页不是最后一页时添加next
                output.next = this.currentPage + 1;
            } else {
                output.next = totalPages;
            }
            output.last = totalPages; // 在当前页面没有达到最后一页时添加last
            output.current = this.currentPage; //标记当前页面
            output.total = totalPages;
            output.numberOfPages = this.options.numberOfPages;
            return output;
        },

        /**
         * 从选项中获取值,这是为了处理其中value是函数的返回值的情况。
         *
         * @return 混合值取决于参数的类型,如果给定参数是函数,则返回评估结果。 否则参数本身将返回。
         * */
        getValueFromOption: function(value) {
            var output = null,
                args = Array.prototype.slice.call(arguments, 1);
            if(typeof value === 'function') {
                output = value.apply(this, args);
            } else {
                output = value;
            }
            return output;
        }
    };
    old = $.fn.bootstrapPaginator;
    $.fn.bootstrapPaginator = function(option) {
        var args = arguments,
            result = null;
        $(this).each(function(index, item) {
            var $this = $(item),
                data = $this.data('bootstrapPaginator'),
                options = (typeof option !== 'object') ? null : option;

            if(!data) {
                data = new BootstrapPaginator(this, options);

                $this = $(data.$element);

                $this.data('bootstrapPaginator', data);

                return;
            }

            if(typeof option === 'string') {

                if(data[option]) {
                    result = data[option].apply(data, Array.prototype.slice.call(args, 1));
                } else {
                    throw "Method " + option + " does not exist";
                }

            } else {
                result = data.setOptions(option);
            }
        });
        return result;
    };

    $.fn.bootstrapPaginator.sizeArray = {
        "2": {
            "large": "pagination-large",
            "small": "pagination-small",
            "mini": "pagination-mini"
        },
        "3": {
            "large": "pagination-lg",
            "small": "pagination-sm",
            "mini": ""
        }
    };

    $.fn.bootstrapPaginator.defaults = {
        containerClass: "",
        size: "normal",
        alignment: "left",
        bootstrapMajorVersion: 2,
        listContainerClass: "",
        itemContainerClass: function(type, page, current) {
            return(page === current) ? "active" : "";
        },
        itemContentClass: function(type, page, current) {
            return "";
        },
        currentPage: 1,
        numberOfPages: 5,
        totalPages: 1,
        pageUrl: function(type, page, current) {
            return null;
        },
        onPageClicked: null,
        onPageChanged: null,
        useBootstrapTooltip: false,
        shouldShowPage: function(type, page, current) {
            var result = true;
            switch(type) {
                case "first":
                    result = (current !== 1);
                    break;
                case "prev":
                    result = (current !== 1);
                    break;
                case "next":
                    result = (current !== this.totalPages);
                    break;
                case "last":
                    result = (current !== this.totalPages);
                    break;
                case "page":
                    result = true;
                    break;
            }
            return result;
        },
        itemTexts: function(type, page, current) {
            switch(type) {
                case "first":
                    return "首页";
                case "prev":
                    return "上一页";
                case "next":
                    return "下一页";
                case "last":
                    return "末页";
                case "page":
                    return page;
            }
        },
        tooltipTitles: function(type, page, current) {
            switch(type) {
                case "first":
                    return "首页";
                case "prev":
                    return "上一页";
                case "next":
                    return "下一页";
                case "last":
                    return "末页";
                case "page":
                    return(page === current) ? "当前是第" + page + "页" : "第" + page + "页";
            }
        },
        bootstrapTooltipOptions: {
            animation: true,
            html: true,
            placement: 'top',
            selector: false,
            title: "",
            container: false
        }
    };
    $.fn.bootstrapPaginator.Constructor = BootstrapPaginator;
}(window.jQuery));

前端导入js文件

    <%--此路径根据个人存放地址而定--%>
    <script src="common\js\bootstrap-paginator.js"></script>

示例代码

<!DOCTYPE>
<html>
<head>
    <script src="common\js\bootstrap-paginator.js"></script>
    <script type="text/javascript">
        $(function () {
            var currentPage = 1
            var totalPages = 5
            $("#page").bootstrapPaginator({
                bootstrapMajorVersion: 3, //对应的bootstrap版本
                currentPage: currentPage, //当前页数
                numberOfPages: 20, //每次显示页数
                totalPages: totalPages, //总页数
                shouldShowPage: true, //是否显示该按钮
                useBootstrapTooltip: true,
                onPageClicked: function (event, originalEvent, type, page) {
					 console.error("PAGE = "+ page)
                }
            });
        });
    </script>
  
</head>
<body>
    <div>
        <ul id="page"></ul>
    </div>
</body>
</html>

项目实战

我是写在jsp内的,前后端未分离这样的状态下

Controller

@Controller
@RequestMapping("/")
public class TextController {
@RequestMapping(value = "editInfoList")
    public String editInfoList(HttpServletRequest request, HttpServletResponse response, Model model,
                                      @RequestParam(required = false, value = "uid") String uid,
                                      @RequestParam(required = false, value = "pageno", defaultValue = "1") Integer pageno,
                                      @RequestParam(required = false, value = "pagesize", defaultValue = "20") Integer pagesize) {

        List<Info> list = null;
        int totalCount= 0;
        try {
 			//获取列表数据
            list =InfoService.getInfoList(uid, pageno, pagesize);
            //获取总条目数
            totalCount= InfoService.getInfoTotalCount();
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }

        if (list == null) {
            list = new ArrayList<Info>();
        }
        
		//这里是我在bean里面用于存储页数、总数 (方式很多)
        list.get(0).setTotalCount(totalCount);
        list.get(0).setPageno(pageno);

		//数据校验,提升健壮性
        if (uid!=null&&uid!=""&&!uid.equals("null")){
            model.addAttribute("uid", uid);
        }

		//传值 → jsp内
        model.addAttribute("infolist", list);
        //返回自己的jsp页面 test/pagelist 为jsp存放地址
        return "test/Infolist";
    }
}

Infolist.jsp


<%
    // <% 这个区间可以使用java代码%> 这里我们获取从Controller 传递过来的值
    List<Info> infolist = (List<Info>) request.getAttribute("infolist");
    String uid = (String) request.getAttribute("uid");
%>
<!DOCTYPE>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css" href="common/css/bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="common/css/jquery-ui.css"/>
    <script type="text/javascript" src="common/js/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="common/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="common/js/jquery.form.min.js"></script>
    <script src="common\js\bootstrap-paginator.js"></script>

    <script type="text/javascript">
    
        $(function () {     
            <%
            //数据组合
             DecimalFormat df=new DecimalFormat("0.00");
             String temp = df.format((float)infoList.get(0).getTotalCount()/20);
             Integer pageno = confList.get(0).getPageno();
             int totalPage=(int) Math.ceil(Double.parseDouble(temp));
            %>

			<%-- 数据赋值 --%>
            var currentPage = <%= pageno %>;
            var totalPages = <%= totalPage%>;
            
            $("#page").bootstrapPaginator({
                bootstrapMajorVersion: 3, //对应的bootstrap版本
                currentPage: currentPage, //当前页数
                numberOfPages: 20, //每次显示页数
                totalPages: totalPages, //总页数
                shouldShowPage: true, //是否显示该按钮
                useBootstrapTooltip: true,
                onPageClicked: function (event, originalEvent, type, page) {
                    $("input[name='pageno']").val(page);
                    currentPage = page;
                    $("#listform").submit();
                }
            });
        });
    </script>
    <title>信息列表</title>
</head>
<body>
<div style="height:20px;"></div>
<div class="container">
    <div style="height:20px;"></div>
    <table class="table">
        <tr>
            <th>姓名</th>
            <th>年龄</th>
        </tr>
        <%
            for (Info user: infolist ) {
        %>
        <tr userid="<%=user.id() %>">
            <td><%=user.getName() %>
            </td>
            <td><%=user.getAge() %>
            </td>
        </tr>
        <%} %>
    </table>

    <div>
        <ul id="page"></ul>
    </div>
</div>

<%-- 隐藏的form作用域 --%>
<form id="listform" action="/surveylogic/editlogicconflist" method="get">
    <%if (uid != null && uid != "") { %>
    <input type="hidden" name="uid" value="<%=uid%>"/>
    <%}%>
    <input type="hidden" name="pageno" value=""/>
</form>

</body>
</html>

共性问题

  • controller传值到jsp

controller

    model.addAttribute("uid", uid);

jsp

<%
    String uid = (String) request.getAttribute("uid");
%>
  • 分页数量
   <%
     DecimalFormat df=new DecimalFormat("0.00");
     String temp = df.format((float)infoList.get(0).getTotalCount()/20);
     //当前分页
     Integer pageno = confList.get(0).getPageno();
     //计算分页数量  如:100条数据每页20条,分五页
     int totalPage=(int) Math.ceil(Double.parseDouble(temp));
    %>
  • 数据赋值
     var currentPage = <%= pageno %>;
     var totalPages = <%= totalPage%>;
  • 数据提交

利用表单隐藏域存储数据

<%-- 隐藏的form作用域 --%>
<form id="listform" action="/surveylogic/editInfoList" method="get">
    <%if (uid != null && uid != "") { %>
    <input type="hidden" name="uid" value="<%=uid%>"/>
    <%}%>
    <input type="hidden" name="pageno" value=""/>
</form>

使用表单提交

//主要代码
 $("input[name='pageno']").val(page);
 currentPage = page;
 $("#listform").submit();

//较全代码
 $("#page").bootstrapPaginator({
        bootstrapMajorVersion: 3, //对应的bootstrap版本
        currentPage: currentPage, //当前页数
        numberOfPages: 20, //每次显示页数
        totalPages: totalPages, //总页数
        shouldShowPage: true, //是否显示该按钮
        useBootstrapTooltip: true,
        onPageClicked: function (event, originalEvent, type, page) {
            $("input[name='pageno']").val(page);
            currentPage = page;
            $("#listform").submit();
        }
    });
 });

  • 页面跳转刷新之后,分页数一直在第一页

controller动态存储pageno

    list.get(0).setPageno(pageno);
 或
    model.addAttribute("pageno", pageno);

jsp动态取出pageno

	<% 
	 Integer pageno = infoList.get(0).getPageno()
	%><% 
	 String pageno = (String) request.getAttribute("pageno ");
	%>
发布了247 篇原创文章 · 获赞 97 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/qq_20451879/article/details/100120125