您的位置:首页 > Web前端 > BootStrap

简单叨叨bootstrap按钮无限层级下拉菜单的实现

2017-11-06 17:24 453 查看

0、写在前面的话

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

1、bootstrap的按钮下拉菜单栏

bootstrap是有直接可以使用的下拉菜单插件的:Bootstrap下拉菜单(Dropdown)插件


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

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

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



可以看到这个效果绝对是非常棒了,that'swhatIwant!
说动手就动手,通过作者给的demo可以看到:
<liclass="offset-leftdropdown">

<ahref="#"class="dropdown-toggle">Dropdown...</a>

<ulclass="dropdown-menu">

<li><ahref="#">Secondarylink</a></li>

<li><ahref="#">Somethingelsehere</a></li>

<li><ahref="#">Somethingelsehere</a></li>

<liclass="divider"></li>

<li><ahref="#">Anotherlink</a></li>

</ul>

</li>

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

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

3.1struts标签的失败和启示

前端页面使用的JSP,项目使用了Struts,所以前端是可以直接使用struts的标签的。也就是说,列表实体类可以直接通过struts抓取其中的属性List,再通过<s:iterator>,如<s:iteratorvalue="category.childCategoryList">,然后通过ifelse判定,如果没有子类,则设定其样式形为<li><a></a></li>,如果有子类,则设定其样式形为<liclass="offset-leftdropdown"><ahref="#"class="dropdown-toggle">MenuName</a><ulclass="dropdown-menu"><li><a></a></li></ul></li>
然而问题在于,每当子节点存在下一层子节点,我又必须增加一层ifelse判定,假如规定子分类最多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":"测试"

}

]

[/code]

3.2递归生成html

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

<divclass="btn-group">

<buttonid="categoryButton"idx="0"type="button"class="btnbtn-defaultdropdown-toggle"data-toggle="dropdown"style="width:215px">

请选择图片分类<spanclass="caret"></span>

</button>

<!--图片分类的下拉菜单列表,通过js加载数据-->

<ulid="categories"class="dropdown-menu"role="menu">

<!--loadingdatainhere-->

</ul>

</div>

</td>

[/code]
后端给前端传递的json数据,变量名这里为categories,即如下的vardata,那么接下来通过一个递归方法:
varglb_str="";

functioncreateCategoryTree(data){

varflag;

for(vari=0;i<data.length;i++){

varnodeText=data[i]['text'];

varnodeId=data[i]['id'];

varchildren=data[i]['children'];

//若有子分类,则遍历子分类

if(children.length>0){

flag=true;

glb_str+="<liclass='offset-rightdropdown'><aclass='category'"+"id="+nodeId+"href='#'>"+nodeText+"...</a><ulclass='dropdown-menu'>"

createCategoryTree(children);

}else{

//若没有子分类

flag=false;

glb_str+="<li><aclass='category'"+"id="+nodeId+"href='#'>"+nodeText+"</a>";

}


if(flag){

glb_str+="</ul></li>"

}else{

glb_str+="</li>";

}

}

returnglb_str;

}


//以上为方法定义,该处为调用

vardata=${categories};

varresult=createCategoryTree(data);

$("#categories").append(result);

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

4、参考链接

Bootstrap下拉菜单(Dropdown)插件

为bootstrapdropdown增加无限级子菜单

JSP+Struts2怎么做递归树形下拉列表

从数组遍历谈一下js中的递归调用

赶时间,写得潦草了些,就这样吧~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: