1. 程式人生 > >無限級菜單簡單的設計

無限級菜單簡單的設計

是否 包含 bottom -a color htm sta code incr

策略:數據庫就一張表,前端查詢出所有的可顯示的菜單,在前端進行循環展示。

1,數據庫表的設計

CREATE TABLE sys_menu (
  id     INT         NOT NULL  AUTO_INCREMENT,
  name   VARCHAR(64) NOT NULL,
  url    VARCHAR(255),
  pid    INT         NOT NULL  DEFAULT 0,
  isLeaf TINYINT     NOT NULL  DEFAULT 1
  COMMENT 0表示不是葉子,1表示是葉子,
  status TINYINT     NOT
NULL DEFAULT 1 COMMENT 0表示禁用,1表示啟用, seq TINYINT NOT NULL DEFAULT 0 COMMENT 同級中的順序,0-n,從上到下, PRIMARY KEY (id) );

把菜單當作一個多叉樹,root節點為虛擬節點,id為0。第一層節點表示一級菜單,以此類推。其中,isLeaf表示該菜單是不是葉子節點。

簡單的填充數據如下所示:

技術分享

2,查詢所有菜單的接口(略,簡單的sql查詢)

需要過濾status=0,也就是禁用的菜單。

3,前端展示

3.1 html代碼和css樣式

body中就是如下簡單的代碼

<body>
<ul class="Menue">
</ul>
</body>

css樣式(從網上隨便找的)

<style type="text/css">
        a {
            text-decoration: none;
        }

        ul, li {
            list-style: none;
            margin: 0;
            padding: 0;
        }

        /*定義菜單*/

        .Menue li {
            background: #111;
            color: #fff;
            height
: 30px; line-height: 30px; position: relative; float: left; margin-right: 5px; width: 100px; text-align: center; font-family: Arial, Helvetica, sans-serif; } .Menue li a { color: #fff; font-size: 14px; display: block; } /*下拉菜單樣式*/ ul.sub_menu { position: absolute; width: 100px; display: none; z-index: 999; } .Menue li ul.sub_menu li { background: none; color: #555; font-size: 12px; border-bottom: 1px #333 solid; position: relative; width: 100px; height: 30px; } .Menue li ul.sub_menu li.last { border-bottom: none; } /*js會對最後一個li添加該class,去掉border-bottom效果*/ .Menue li ul.sub_menu li a { background: #222; color: #888; display: block; height: 30px; } .Menue li ul.sub_menu li a:hover, .Menue li ul.sub_menu li a.now { background: #f90; color: #fff; } .Menue li.now, .Menue li.current { background: #f60; color: #fff; } /*如果有下拉菜單添加的class*/ .hasmenu { background: url(arrow.png) no-repeat right; padding-right: 15px; } /*主導航箭頭向下*/ .Menue li a.hasmenu { background: url(arrow.png) no-repeat right; padding-right: 15px; background-position: right -30px; } /*下拉菜單箭頭向右*/ .Menue li ul.sub_menu li a.hasmenu { background: #222 url(arrow.png) no-repeat right top; } .Menue li ul.sub_menu li a.hasmenu:hover { background: #f90 url(arrow.png) no-repeat right top; color: #fff; } </style>

3.2 jquery ajax獲取所有的菜單數據

$.ajax({
        type: "GET",
        url: "<%=request.getContextPath()%>/menu/getMenus.do",
        dataType: "json",
        success: function (result) {
            if (result.status > 0) {
                //獲取到菜單數據,進行展示
                //1,展示頂級菜單
                var list = result.body;
                var i;
                for (i = 0; i < list.length; i++) {
                    //console.log(typeof list[i].url == ‘undefined‘);//如果url不存在,則為undefined,應該用typeof判斷
                }
                //$(".Menue").html("");
                $(".Menue").html(showFirstLevelMenu(list));
                console.log(showFirstLevelMenu(list))
                //在菜單全部顯示後,增加hover件事
                addHover();
            } else {
                alert(result.message);
            }
        },
        error: function () {
            alert("服務器故障,請刷新或稍後重試!");
        }
    })

當獲取到數據後,將數據拼裝成節點html數據,設置到class=Menu的ul中。然後對動態添加的html代碼段加上hover事件

$(".Menue").html(showFirstLevelMenu(list));
//在菜單全部顯示後,增加hover事件
addHover();

3.3 遞歸拼接

使用遞歸調用實現拼接子菜單

function showFirstLevelMenu(list) {
        //class = Menu_li
        //遍歷list找到
        var menu = "";
        var subList = new Array();
        var i;
        for (i = 0; i < list.length; i++) {
            if (list[i].pid == 0) {
                subList.push(list[i]);
            }
        }
        subList.sort(function (a, b) {
            return a.seq - b.seq;//從小到大排序
        });
        alert(subList.length)
        for (i = 0; i < subList.length; i++) {
            menu += ‘<li class="Menue_li">‘ + showSubMenu(list, subList[i]) + ‘</li>‘;
        }
        return menu;
    }

    function showSubMenu(list, menuInfo) {
        //class = sub_menu
        var menu = ‘<a href="#">‘ + menuInfo.name + ‘</a>‘;
        if (menuInfo.isLeaf == 0) {//有子菜單
            var subList = new Array();
            var i;
            for (i = 0; i < list.length; i++) {
                if (list[i].pid == menuInfo.id) {
                    subList.push(list[i]);
                }
            }
            if (subList.length != 0) {
                subList.sort(function (a, b) {
                    return a.seq - b.seq;//從小到大排序
                });
                menu += ‘<ul class="sub_menu">‘;
                for (i = 0; i < subList.length; i++) {
                    menu += ‘<li>‘ + showSubMenu(list, subList[i]) + ‘</li>‘;
                }
                menu += ‘</ul>‘;
            }
        }
        return menu;
    }

3.4 hover事件(網上粘貼的)

function addHover() {

        //為導航設置默認高亮 與本菜單無關

        $("ul.Menue li.Menue_li:eq(0)").addClass("current")

        /*jquery menu 開始*/

        //為子菜單的最後一個li添加樣式,適合為li添加下劃線時去除最後一個的下劃線

        $(".sub_menu").find("li:last-child").addClass("last")

        //遍歷全部li,判斷是否包含子菜單,如果包含則為其添加箭頭指示狀態

        $(".Menue li").each(function () {

            if ($(this).find("ul").length != 0) {
                $(this).find("a:first").addClass("hasmenu")
            }

        })


        //

        $(".Menue li").hover(function () {

            $(this).addClass("now");

            var menu = $(this);

            menu.find("ul.sub_menu:first").show();

        }, function () {

            $(this).removeClass("now");

            $(this).find("ul.sub_menu:first").hide();

        });


        var submenu = $(".sub_menu").find(".sub_menu")

        submenu.css({left: "100px", top: "0px"})

        $(".sub_menu li").hover(function () {

            $(this).find("a:first").addClass("now")

            $(this).find("ul:first").show();

        }, function () {

            $(this).find("a:first").removeClass("now")

            $(this).find("ul:first").hide()

        });

        /*jquery menu 結束*/

    }

3.5 最終頁面顯示結果

技術分享=====>>技術分享=====>>技術分享

無限級菜單簡單的設計