0、写在前面的话

最近看书都懈怠了,又正值新项目,虽说并不是忙得不可开交,好吧我老实交待,我就是偷懒了其实,博客也没更。言归正传,对于前端的不熟悉现在确实是个让我头疼的事情,以至于一些功能要在网络上漫天飞舞疯狂尝试才能做得出来,关键是特别费时间,确实得抽时间补补前端的基础才是。这次要实现一个分类选择,即图片上传之前,抓取所有的图片分类,然后在上传页面做成下拉菜单栏进行选择。效果如下图,理论上要达到无限层级的下拉菜单:
 

1、bootstrap的按钮下拉菜单栏

bootstrap是有直接可以使用的下拉菜单插件的:
 
如上图,这个效果差不多就是我们想要的样式了,可是该插件是不支持无限层级分支的,也就是说只有如上图方式的主菜单“Java”和其子项。

2、无限层级的bootstrap按钮下拉菜单栏

然而网友的力量是强大的,在bootstrap按钮下拉菜单栏的基础上,网友拓展实现了无限层级子菜单,参见:


可以看到这个效果绝对是非常棒了,that's what I want!

说动手就动手,通过作者给的demo可以看到:
<li class="offset-left dropdown">
<a href="#" class="dropdown-toggle">Dropdown...</a>
<ul class="dropdown-menu">
<li><a href="#">Secondary link</a></li>
<li><a href="#">Something else here</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Another link</a></li>
</ul>
</li>
10
 
1
<li class="offset-left dropdown"> 
2
    <a href="#" class="dropdown-toggle">Dropdown...</a>
3
    <ul class="dropdown-menu">
4
        <li><a href="#">Secondary link</a></li>
5
        <li><a href="#">Something else here</a></li>
6
        <li><a href="#">Something else here</a></li>
7
        <li class="divider"></li>
8
        <li><a href="#">Another link</a></li>
9
    </ul>
10
</li>

凡是有子菜单延伸的条目,由普通的<li><a></a></li>变成如上形式即可。

3、前后端交互,前端数据的展示

3.1 struts标签的失败和启示

前端页面使用的JSP,项目使用了Struts,所以前端是可以直接使用struts的标签的。也就是说,列表实体类可以直接通过struts抓取其中的属性List,再通过<s:iterator>,如<s:iterator value="category.childCategoryList">,然后通过if else判定,如果没有子类,则设定其样式形为<li><a></a></li>,如果有子类,则设定其样式形为<li class="offset-left dropdown"><a href="#" class="dropdown-toggle">MenuName</a><ul class="dropdown-menu"><li><a></a></li></ul></li>

然而问题在于,每当子节点存在下一层子节点,我又必须增加一层if else判定,假如规定子分类最多4层,那么我的if判定也就写4层好了,可是我们这个是理论上无限层级,假如用户就是不断建立分类细化,那怎么办?显然,这种方式是不合理的,而struts标签页没有其他更好的方式来解决这种问题。

这种失败在于数据的局限性,数据应该是后台处理好之后传给前端,仅由前端来展示即可,而如上struts是将数据一股脑丢到前台,由前端来筛选组合处理,再进行展示,麻烦不言而喻。所以实际上应该将数据处理好,固化后再给前端解析使用。一旦数据结构固化,前端通过分析该数据,也就知道怎么做了。现在一般是使用Json,所以在我自己的这个例子中,我将后端的分类和子分类之间的关系,在后端转换成json,传递给了前端,json结构如下:
[
{
"children": [
{
"children": [
{
"children": [],
"id": 10,
"text": "公司"
},
{
"children": [],
"id": 11,
"text": "兼职"
}
],
"id": 3,
"text": "工作"
},
{
"children": [],
"id": 4,
"text": "生活"
},
{
"children": [],
"id": 5,
"text": "个人"
}
],
"id": 2,
"text": "日常"
},
{
"children": [],
"id": 6,
"text": "高清大图"
},
{
"children": [
{
"children": [],
"id": 8,
"text": "修改"
},
{
"children": [],
"id": 9,
"text": "测试回调"
}
],
"id": 7,
"text": "测试"
}
]
55
 
1
[
2
  {
3
    "children": [
4
      {
5
        "children": [
6
          {
7
            "children": [],
8
            "id": 10,
9
            "text": "公司"
10
          },
11
          {
12
            "children": [],
13
            "id": 11,
14
            "text": "兼职"
15
          }
16
        ],
17
        "id": 3,
18
        "text": "工作"
19
      },
20
      {
21
        "children": [],
22
        "id": 4,
23
        "text": "生活"
24
      },
25
      {
26
        "children": [],
27
        "id": 5,
28
        "text": "个人"
29
      }
30
    ],
31
    "id": 2,
32
    "text": "日常"
33
  },
34
  {
35
    "children": [],
36
    "id": 6,
37
    "text": "高清大图"
38
  },
39
  {
40
    "children": [
41
      {
42
        "children": [],
43
        "id": 8,
44
        "text": "修改"
45
      },
46
      {
47
        "children": [],
48
        "id": 9,
49
        "text": "测试回调"
50
      }
51
    ],
52
    "id": 7,
53
    "text": "测试"
54
  }
55
]

3.2 递归生成html

有了数据,只需要通过数据解析,然后组成相关的html代码即可。如上的json结构,可以看到只要有chidren属性不为空,那么我们就可以在该部分生成子菜单形式的样式,否则使用普通的样式。这里就要用到递归了,因为是无限层级,否则使用if判定则又和struts一样进入了死胡同。

菜单部分的html是通过数据和算法生成的,不是固定的,需要提醒一下。则正常时空空如也:
<td>分类<b>*</b><br/>
<div class="btn-group">
<button id="categoryButton" idx="0" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" style="width:215px">
请选择图片分类<span class="caret"></span>
</button>
<!--图片分类的下拉菜单列表,通过js加载数据-->
<ul id="categories" class="dropdown-menu" role="menu">
<!--loading data in here-->
</ul>
</div>
</td>
11
 
1
<td>分类<b>*</b><br/>
2
    <div class="btn-group">
3
        <button id="categoryButton" idx="0" type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" style="width:215px">
4
            请选择图片分类<span class="caret"></span>
5
        </button>
6
        <!--图片分类的下拉菜单列表,通过js加载数据-->
7
        <ul id="categories" class="dropdown-menu" role="menu">
8
            <!--loading data in here-->
9
        </ul>
10
    </div>
11
</td>

后端给前端传递的json数据,变量名这里为categories,即如下的var data,那么接下来通过一个递归方法:
var glb_str = "";
function createCategoryTree(data) {
var flag;
for (var i = 0; i < data.length; i++) {
var nodeText = data[i]['text'];
var nodeId = data[i]['id'];
var children = data[i]['children'];
//若有子分类,则遍历子分类
if(children.length > 0) {
flag = true;
glb_str += "<li class='offset-right dropdown'><a class='category' " + "id=" + nodeId + " href='#'>" + nodeText + "...</a><ul class='dropdown-menu'>"
createCategoryTree(children);
} else {
//若没有子分类
flag = false;
glb_str += "<li><a class='category' " + "id=" + nodeId + " href='#'>" + nodeText + "</a>";
} if (flag) {
glb_str += "</ul></li>"
} else {
glb_str += "</li>";
}
}
return glb_str;
} //以上为方法定义,该处为调用
var data = ${categories};
var result = createCategoryTree(data);
$("#categories").append(result);
x
 
1
var glb_str = "";
2
function createCategoryTree(data) {
3
    var flag;
4
    for (var i = 0; i < data.length; i++) {
5
        var nodeText = data[i]['text'];
6
        var nodeId = data[i]['id'];
7
        var children = data[i]['children'];
8
        //若有子分类,则遍历子分类
9
        if(children.length > 0) {
10
            flag = true;
11
            glb_str += "<li class='offset-right dropdown'><a class='category' " + "id=" + nodeId + " href='#'>" + nodeText + "...</a><ul class='dropdown-menu'>"
12
            createCategoryTree(children);
13
        } else {
14
            //若没有子分类
15
            flag = false;
16
            glb_str += "<li><a class='category' " + "id=" + nodeId + " href='#'>" + nodeText + "</a>";
17
        }
18

19
        if (flag) {
20
            glb_str += "</ul></li>"
21
        } else {
22
            glb_str += "</li>";
23
        }
24
    }
25
    return glb_str;
26
}
27
 
28
//以上为方法定义,该处为调用
29
var data = ${categories};
30
var result = createCategoryTree(data);
31
$("#categories").append(result);

加载完成的页面,可以看到,页面源码中已经有列表的html代码了:
 

4、参考链接


赶时间,写得潦草了些,就这样吧~

简单叨叨bootstrap按钮无限层级下拉菜单的实现的更多相关文章

  1. Bootstrap入门(十)组件4:按钮组与下拉菜单结合

    Bootstrap入门(十)组件4:按钮组与下拉菜单结合   先引入本地的CSS文件和JS文件(注:1.bootstrap是需要jQuery支持的.2.需要在<body>当中添加) < ...

  2. Bootstrap <基础十二>下拉菜单(Dropdowns)

    Bootstrap 下拉菜单.下拉菜单是可切换的,是以列表格式显示链接的上下文菜单.这可以通过与 下拉菜单(Dropdown) JavaScript 插件 的互动来实现. 如需使用下列菜单,只需要在 ...

  3. Bootstrap历练实例:下拉菜单插件方法的使用

    <!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...

  4. BootStrap学习(2)_下拉菜单&按钮组

    一.下拉菜单 1.基本下拉菜单 如需使用下列菜单,只需要在class .dropdown 内加上下拉菜单即可.下面的实例演示了基本的下拉菜单: <!DOCTYPE html> <ht ...

  5. Bootstrap 字体图标、下拉菜单、按钮组

    Bootstrap 字体图标(Glyphicons) 需要引入fonts文件夹中的文件,而且该文件夹必须命名为fonts,然后引进css文件,jQuery文件,以及bootstrap的js文件. 用法 ...

  6. Bootstrap中的各种下拉菜单

    @*基本下拉菜单与按钮下拉菜单的样式完全一致.不过,基本的下拉菜单使用<div class="dropdown">包裹,所有要换行.而按钮式下拉菜单<div cl ...

  7. bootstrap和JS实现下拉菜单

    // bootstrap下拉菜单 <div class="btn-group"> <button id="button_text" type= ...

  8. ⑧bootstrap组件 文字图片 下拉菜单 按钮组 使用基础案例

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Delphi 工具条按钮上的下拉菜单

    制作步骤: 1.添加一个 TImageList: ImageList1, 然后载入些图标; 2.添加两个 TPopupMenu: PopupMenu1.PopupMenu2, 并分别添加些菜单项; 3 ...

随机推荐

  1. photoSwiper移动端图片双击手势缩放

    首先引入几个文件: <link rel="stylesheet" type="text/css" href="css/photoswipe.cs ...

  2. JavaSE——TCP协议网络编程(一)

    实现客户端与服务端的连接: 创建TCP服务端的 ServerSocket ServerSocket :此类实现服务器套接字.服务器套接字请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结 ...

  3. Android Studio支持Java1.8的解决方案

    Java1.8新添了一些特性,比如对lambda表达式的支持,父类推断等等,这篇文章讲述了1.8的新特性,有兴趣的同学可以点进去看看.但是由于AndroidStudio并不能直接支持Java1.8,我 ...

  4. DevOps之基础设施-电力

    唠叨话 关于噢屁事的知识点,仅提供精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <基础设施-电力> 关于基础设施的电力部分,知识与技能的层次(知道.理解.运用),理论与实践的 ...

  5. svn其它

    参考地址: http://www.cnblogs.com/mymelon/p/5483215.html

  6. eclipse neon配置tomcat8无法显示默认页面解决方法

    下载对应tomcat8版本到本地后,在eclipse中添加tomcat8的对应目录,输入http://localhost:8080时无法显示tomcat的index.jsp页面(会显示404页面).原 ...

  7. Java修改服务器(tomcat)响应头 Server:Apache-Coyote/1.1

    Server:Apache-Coyote/1.1 :很多人有说有漏洞,是否有没研究过, 只知道Apache-Coyote是tomcat处理socket链接信息,包装request.response等底 ...

  8. Sql Server2008R2下载地址

    ed2k://%7Cfile%7Ccn_sql_server_2008_r2_enterprise_x86_x64_ia64_dvd_522233.iso%7C4662884352%7C1DB0252 ...

  9. Cisco DHCP 配置方法

    首先假设两台思科路由器,R1(服务端)连接R2(客户端),组成一个简单的链式局域网,下面就来实现DHCP,配置的命令及其解释如下: 1.R1 dhcp服务的配置 dhcp#configure term ...

  10. 常用的 接口访问方法 post 和get

    public string GetFunction(string serviceAddress) { HttpWebRequest request = (HttpWebRequest)WebReque ...