无限级菜单简单的设计

策略:数据库就一张表,前端查询出所有的可显示的菜单,在前端进行循环展示。

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 最终页面显示结果

=====>>=====>>

时间: 2024-08-05 15:26:44

无限级菜单简单的设计的相关文章

jquery,tree无限级树形菜单+简单实用案例

jquery,tree无限级树形菜单+简单实用案例 我在项目中用到产品类别的树形.各种地方都要用. 我就封装起来,方便以后调用. 记录下来,希望给新手们提供帮助.要记得导入jquery.js  tree.js 哦 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri=&quo

可以固定的顶部的导航菜单简单实例代码

可以固定的顶部的导航菜单简单实例代码:固定于网页顶部的导航栏效果在当下网站比较流行,所谓的固定于网页的顶部一般来说并不是一直固定于顶部,而是在开始是位于某一个位置,当下拉滚动条使其到达顶部的时候才会固定在顶部,下面通过代码实例介绍一下如何实现此效果.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" con

ASP.NET中登录功能的简单逻辑设计

 ASP.NET中登录功能的简单逻辑设计                               概述                               逻辑设计                               1.接收参数                               2.判断参数合法性                               3.访问数据库                               4.保存Session     

简单数据库设计--山里有个庙

最近在学习数据库,但很少看到有适合入门的设计参考,故写下一个自己的实际 设计以备忘. 首先,我们来讲一个故事: 从前有座山,山里有座庙(temple),庙里住着一位老和尚(monk),他给小和尚们讲故事,故事是这样的:从前这座山上有很多座庙,而且不止这一座山上有庙,附近很多山上都有庙,但是没有一座庙可以建在两座或者更多山上,也没有任何两座庙的名字是重复的.每个和尚只能属于一座庙,他们都有一个法号, 和尚的法号是不会重复的.当一名和尚的年龄足够高(每座庙的阈值有所不同) ,他就可以成为老和尚.每座

对App数据库元素进行简单的设计

假如对<豆瓣>进行简单的数据库元素设计; 分析页面: 简单的豆瓣一共有以下页面{ 活动页面 活动详情页面 电影页面 电影详情页面 影院页面(一般不用到数据库,不及于数据库考虑) 我的{ 活动收藏页面 电影收藏页面 注册登录页面 } } 按照以上页面考虑 Model,是主要的数据库对象 即,将所有model存入数据库 详细分类以及设置对应缺陷........ "我的"页面中有收藏功能以及注册登录 这就是数据库会应用到的地方 使用单个数据库,多个表存储各类数据 活动页面对应收藏

CSS导航菜单简单示例

1.纵向菜单 纵向菜单代码示例 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>纵向导航菜单</title> <style type="text/css"> *{ margin: 0; padding: 0; } nav{ width: 150px; margin: 50p

右击菜单简单实现

前几天项目验收的时候,提出"右击菜单"的需求.那么右击菜单有什么优点呢?为什么要做成这样?我想用一句:"提高用户体验度"就能够解除大家的疑惑吧.这样用户就能够依据自己的喜好,是点击固定button还是右击,无论通过那个渠道都能够达到目的,这样才干得到用户的青睐. 那么接下来就让我先从一个小的demo入手,体验一把吧! 一.准备工作 想要做的效果: 二.HTML代码 <span style="font-size:18px;"><!

使用postgre数据库实现树形结构表的子-父级迭代查询,通过级联菜单简单举例

前言:开发常用的关系型数据库MySQL,mssql,postgre,Oracle,简单的增删改查的SQL语句都与标准SQL兼容,这个不用讲,那么对于迭代查询(不严格的叫法:递归查询)每种数据库都不一样,对于标准SQL语句支持最好的是mssql和postgre,这个不需多讲,我们只讲讲单表情况下的postgre如何通过迭代查询获取有层级关系的数据. 一.表结构举例 MENU表 ID VARCHAR2(32)     N   sys_guid()    节点idFENXID VARCHAR2(32)

php大力力 [031节] php设计系统后台菜单和样式设计

耗掉我一整夜的时间,把后台html设计了一个,对于我这样的html白痴,实属不容易啊. 留下一点点网上查找的网页知识: 索马里论坛群发简介 (自动注册,自动发帖,自动回帖,自动搜索论坛,免费试用) EC营客通,王牌销售经理必备神器,腾讯战略产品,免费试用 极客学院 安卓学习 微软Snip发布:最强免费录屏工具 可以加声音和和注释 40个色彩搭配优秀的网站配色(5) 配色网 在线配色方案自动生成器 两种 js下载文件的方法(转) 下载文件的一种简单方法js (2009-01-20 10:32:42