一,什么是动态选项卡?
在一个界面或者应用中,可根据用户的操作或输入动态变化内容的选项卡。通常情况下,每个选项卡代表着不同的功能或者内容,当用户切换选项卡时,界面会相应地更新展示对应的内容。动态选项卡的优势在于它可以提供更多内容和功能的展示空间,同时方便用户快速切换不同的信息或功能,提高用户体验。它常被应用于网页、移动应用、软件界面等场景中,以提供更好的信息组织和交互方式。
二,优点(为什么使用)
- 更好的信息组织:动态选项卡提供了一种清晰、有组织的方式来展示不同类型的内容或功能。用户可以根据自己的需求选择特定的选项卡,从而快速找到所需的信息或功能
- 省略繁琐的页面刷新:通过使用动态选项卡,用户可以在不离开当前界面的情况下切换到其他内容,无需重新加载整个页面或返回上级菜单。这样可以大大节省时间和提高用户的使用效率
- 更多展示空间:动态选项卡可以提供更多的展示空间,以容纳更多的内容或功能。通过切换选项卡,用户可以在有限的屏幕空间内访问和浏览更多信息,而无需滚动或翻页查看
- 简化用户界面:动态选项卡可以简化用户界面,减少复杂的菜单层次结构或导航结构。用户只需通过选择适当的选项卡即可访问所需的内容,而无需在多个页面之间来回切换
总的来说,使用动态选项卡可以提高用户体验、节省用户的时间和精力,并使界面结构更清晰,展示更多内容。它是提升界面交互性、简化操作流程的有效方法,使用户能够更轻松地获取所需的信息或功能,从而提高整体的使用效率和满意度。
那该如何使用它呢?第三点会详细讲解o!!!
三,实现动态选项卡
前言:实现该动态选项卡,需要实现树形菜单,该版本是基于实现树形菜单之上的如果不理解,可以参考我所编写树形菜单http://t.csdn.cn/cu5Xk,所点击二级菜单生成相对应的选项卡。
1,在官网copy所需要的选项卡复制到项目中,再给遍历的二级菜单设置一个函数,以便点击二级菜单的时候生成相对应的选项卡
注意:由于大部分公司中,需要去简化代码,所以我们把实现前端jsp代码封装成js到WebContent下的js目录下,到时通过script scr属性引入即可
二级菜单加选项卡jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <%@include file="common/header.jsp"%> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>后台的主界面</title> <!-- 引入 index.js --> <script src="static/js/index.js"></script> </head> <body> <div class="layui-layout layui-layout-admin"> <div class="layui-header"> <div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div> <!-- 头部区域(可配合layui 已有的水平导航) --> <ul class="layui-nav layui-layout-left"> <!-- 移动端显示 --> <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft"> <i class="layui-icon layui-icon-spread-left"></i> </li> <!-- Top导航栏 --> <li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li> <li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li> <li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li> <li class="layui-nav-item"> <a href="javascript:;">nav groups</a> <dl class="layui-nav-child"> <dd><a href="">menu 11</a></dd> <dd><a href="">menu 22</a></dd> <dd><a href="">menu 33</a></dd> </dl> </li> </ul> <!-- 个人头像及账号操作 --> <ul class="layui-nav layui-layout-right"> <li class="layui-nav-item layui-hide layui-show-md-inline-block"> <a href="javascript:;"> <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img"> tester </a> <dl class="layui-nav-child"> <dd><a href="">Your Profile</a></dd> <dd><a href="">Settings</a></dd> <dd><a href="login.jsp">Sign out</a></dd> </dl> </li> <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect> <a href="javascript:;"> <i class="layui-icon layui-icon-more-vertical"></i> </a> </li> </ul> </div> <div class="layui-side layui-bg-black"> <div class="layui-side-scroll"> <ul id="menu" class="layui-nav layui-nav-tree" lay-filter="menu"> <li class="layui-nav-item layui-nav-itemed"> <a class="" href="javascript:;">menu group 1</a> <dl class="layui-nav-child"> <dd><a href="javascript:;">menu 1</a></dd> <dd><a href="javascript:;">menu 2</a></dd> <dd><a href="javascript:;">menu 3</a></dd> <dd><a href="">the links</a></dd> </dl> </li> <li class="layui-nav-item"> <a href="javascript:;">menu group 2</a> <dl class="layui-nav-child"> <dd><a href="javascript:;">list 1</a></dd> <dd><a href="javascript:;">list 2</a></dd> <dd><a href="">超链接</a></dd> </dl> </li> <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li> <li class="layui-nav-item"><a href="">the links</a></li> </ul> </div> </div> <div class="layui-body"> <div class="layui-tab" lay-filter="demo" lay-allowclose="true"> <ul class="layui-tab-title"> <li class="layui-this" lay-id="11">网站设置</li> </ul> <div class="layui-tab-content"> <div class="layui-tab-item layui-show">内容1</div> </div> </div> </div> <div class="layui-footer"> <!-- 底部固定区域 --> </div> </div> <script> //JS </script> </body> </html>
2,在实现树形菜单dao方法中,多用一个map集合来获取前端菜单中的传来的字段。再将集合放到有父子关系的类对象中
Map<String, Object>map= new HashMap<String,Object>();//定义一个map集合 map.put("self", p);//将平级数据中所有字段放入map集合中 vo.setAttributes(map); //将map集合中的数据保存到父子关系的容器中 lst.add(vo);
总代码方法:
package com.zking.dao; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fasterxml.jackson.databind.ObjectMapper; import com.zking.entity.Permission; import com.zking.framework.ActionSupport; import com.zking.framework.ModelDriver; import com.zking.util.BaseDao; import com.zking.util.BuildTree; import com.zking.util.PageBean; import com.zking.util.TreeVo; public class PermissionDao extends BaseDao<Permission> { public List<Permission> list(Permission permission, PageBean pageBean) throws Exception { String sql = "select * from t_oa_permission"; return super.executeQuery(sql, Permission.class, pageBean); } // 将平级数据转换父子关系的数据 public List<TreeVo<Permission>> menus(Permission permission, PageBean pageBean) throws Exception { List<TreeVo<Permission>> lst = new ArrayList<TreeVo<Permission>>(); // 平级数据 List<Permission> list = this.list(permission, pageBean); for (Permission p : list) {// 遍历平级数据 TreeVo<Permission> vo = new TreeVo<>();// 实例TreeVo 方便将平级数据转成父子关系的数据 vo.setId(p.getId() + "");// 转编号 vo.setText(p.getName());// 转名称 vo.setParentId(p.getPid() + "");// 父级id Map<String, Object>map= new HashMap<String,Object>();//定义一个map集合 map.put("self", p);//将平级数据中所有字段放入map集合中 vo.setAttributes(map); //将map集合中的数据保存到父子关系的容器中 lst.add(vo); } return BuildTree.buildList(lst, "-1"); } //测试方法 public static void main(String[] args) throws Exception { PermissionDao pd = new PermissionDao(); List<TreeVo<Permission>> menus = pd.menus(null, null); ObjectMapper om = new ObjectMapper(); System.out.println(om.writeValueAsString(menus)); } }
3,在实现树形菜单我们已实现了前端代码,动态选项卡主要优化了该行代码,外加一个函数接口function实现
htmlStr += '<dd><a href="javascript:;" onclick="opentab(\''+nodel.text+'\',\''+nodel.attributes.self.url+'\',\''+nodel.id+'\')">'+nodel.text+'</a></dd>'
函数接口代码:
//给子菜单添加函数接口 点击菜单生成相对应的选项卡 function opentab(title,content,id){//参数是二级菜单 var $nodel=$('li[lay-id="'+id+'"]') if($nodel.length==0){//当选项卡的长度为0时,不再打开重复的选项卡 element.tabAdd('demo', { title: title//在选项卡展示的标题 ,content: "<iframe frameborder='0' src='"+content+"' scrolling='auto' style='width:100%;height:100%;'></iframe>" //二级菜单text内容 ,id: id //二级菜单id }) } element.tabChange("demo",id);//点击左侧二级菜单右侧选项卡同步选上 }
前段实现总代码:
//将所需要的模块定义在此 用的时候赋值即可 var element,layer,util,$; layui.use(['element', 'layer', 'util'], function(){ element = layui.element ,layer = layui.layer ,util = layui.util ,$ = layui.$; $.ajax({ url:"permission.action?methodName=menus", dataType:'json', success:function(data){ console.log(data); var htmlStr=''; $.each(data,function(i,n){ //拼接一级菜单 开始标签 htmlStr +='<li class="layui-nav-item layui-nav-itemed">'; htmlStr +=' <a class="" href="javascript:;">'+n.text+'</a>'; if(n.hasChildren){//判断是否有子标签 var children=n.children//得到子标签的列表 htmlStr +='<dl class="layui-nav-child">';//拼接子标签 开始标签 $.each(children,function(index,nodel){//遍历子标签 htmlStr += '<dd><a href="javascript:;" onclick="opentab(\''+nodel.text+'\',\''+nodel.attributes.self.url+'\',\''+nodel.id+'\')">'+nodel.text+'</a></dd>' }) htmlStr +='</dl>';//拼接子标签 结束标签 } htmlStr +='</li>'; //拼接一级菜单 结束标签 }) $("#menu").html(htmlStr); element.render('menu');//渲染 } }) }); //给子菜单添加函数 添加新的选项卡 function opentab(title,content,id){//参数选项卡中需要的参数 var $nodel=$('li[lay-id="'+id+'"]') if($nodel.length==0){//当选项卡的长度为0时,不再打开重复的选项卡 element.tabAdd('demo', { title: title//在选项卡展示的标题 ,content: "<iframe frameborder='0' src='"+content+"' scrolling='auto' style='width:100%;height:100%;'></iframe>" //二级菜单text内容 ,id: id //二级菜单id }) } element.tabChange("demo",id);//点击左侧二级菜单右侧选项卡同步选上 }
最后项目运行结果: