在大型PC利用开发中,多tab和多级菜单的形式比拟罕用,如果可能记忆用户上次关上的tab和菜单对用户来说是十分便当的,每次关上零碎就能看到之前关上的页面持续进行浏览,晋升体验和效率,上面咱们来看看如何应用浏览器的存储和layuiTab组件实现这个性能。
首先是次要的顶部layui tab组件的构造,tab外面有个iframe容器,次要应用iframe来当做对应页面的视图,相似vueRouter中的<router-view>,每个一个tab内容都有一个视图,这样就能多个视图独立保留状态,不影响其余tab
咱们菜单对应页面模块文件构造是一个文件夹一个模块,文件夹名就是模块名,文件夹下的index.html就是对应的页面(模块1/index.html),所以在点击时须要存储以后文件夹的名字就能晓得上一次用户关上的模块页面
网站的一级导航构造在这里就不给大家展现了,间接给代码:
<ul id="main-menu" class="font-optimize"> <li id="53a86ff50bbf443fb1a142fd78483ed7" class="homePage_1 sec-menu-item menu-authority-control" > <a href="#" onclick="changeUrl('homePage/index.html','homePage_1',this)" > <p class="fontColor">首页</p> </a> </li> <li id="ff09a2cdd1b941329ff480eed06feb7c" class="seatManagement_1 sec-menu-item menu-authority-control" > <a href="#" onclick="changeUrl('seatManagement/index.html','seatManagement_1',this)" > <p class="fontColor">工作台</p> </a> </li> <li id="84cc08dfaa9047e087ca4104c1e28820" class="WorkOrderManagement_1 sec-menu-item menu-authority-control" > <a href="#" onclick="changeUrl('WorkOrderManagement/workStation.html','WorkOrderManagement_1',this)" > <p class="fontColor">工单治理</p> </a> </li> <li id="d6d8c3f28cc2427ba13fe26170645960" class="BasicSet_1 sec-menu-item menu-authority-control" > <a href="#" onclick="changeUrl('BasicSet/index.html','UserManage',this) " > <p class="fontColor">xxxx</p> </a> </li> </ul> <div class="body-main"> <div class="layui-tab active" lay-filter="mainTab" lay-allowClose="true" style="height: 100%" > <ul class="layui-tab-title"> <li class="layui-this" lay-id="53a86ff50bbf443fb1a142fd78483ed7"> 首页 </li> <li lay-id="ff09a2cdd1b941329ff480eed06feb7c" class="seatManagement"> 坐席工作台 </li> </ul> <div class="layui-tab-content" style="height: calc(100% - 42px)"> <div class="layui-tab-item layui-show"> <div class="report-list"> <iframe id="home" src="./home/index.html" width="100%" height="100%" scrolling="no" marginheight="0" marginwidth="0" ></iframe> </div> </div> <div class="layui-tab-item" style="height: 100%"> ... </div> </div> </div> </div>
这里我给菜单的惟一id设置了哈希值,大家能够本人定义一个语义化的,只有放弃惟一就行
tab局部示例图:
这里是设置首页和工作台的tab不可敞开(暗藏掉敞开按钮)
.body-main .seatManagement{ display: none; } .layui-tab-title > li:first-child .layui-tab-close { display: none; } .layui-tab-title > .seatManagement .layui-tab-close { display: none; } body { padding: 0; } .body-main iframe { background-color: #fff; border: 0px; } .body-main { width: 100%; height: 100%; } .layui-tab-item { height: 100%; }
接下来是js逻辑:
changeUrl为菜单跳转的办法
外围逻辑是在用户关上网站的时候利用浏览器的storage和layuitab的element把之前记忆的tab先一个个创立进去,而后通过记忆的activeMenuId
切换到上次关上的tab:
if (sessionStorage.getItem("lastTabList")) { //把记忆的tab全副创立进去 var crrentTabName = $(".layui-tab.active").attr("lay-filter"); var lastTabList = JSON.parse(sessionStorage.getItem("lastTabList")); lastTabList.forEach(function (i) { element.tabAdd(crrentTabName, { title: i.text, content: '<iframe src="./' + i.url + '" width="100%" height="100%" scrolling="no" marginheight="0" marginwidth="0"></iframe>', //反对传入html id: i.id, }); }); }
而后用户在点击导航的时候,如不存在该tab,也就是用户没有记忆这个菜单的tab,那么咱们就依据传入的url创立新的tab并记忆。
如已存在该tab的话就简略,间接tabChange切换过来就好,tab的内容能够是对应iframe视图,视图里能够有二级菜单,二级菜单的记忆是独自的,文章前面会介绍。
大家可能会纳闷tab里对应的页面是怎么记忆的,其实是咱们在点击菜单跳转的时候就曾经把以后页面的url存储到了storage外面,在下次关上网站时读取记忆并动静增加iframe的形式给显示进去。
留神每次删除和增加新tab的时候都要对storage进行批改(更新一下记忆),增加的时候存储一下以后关上的tab名activeMenuId
残缺代码:
layui.use(["element", "layer"], function () { var element = layui.element; window.changeUrl = function (url, className, e) { $("#main-menu > li").removeClass("selected"); $("#main-menu > ." + url.split("/")[0] + "_1").addClass("selected"); sessionStorage.setItem("url", url); sessionStorage.setItem("className", className); var crrentTabName = $(".layui-tab.active").attr("lay-filter"); var reportName = $(e).parent().attr("id"); if ( url === "homePage/index.html" || url === "seatManagement/index.html" ) { //如为首页或坐席间接切换tab,默认已有页面 element.tabChange(crrentTabName, reportName); return; } //记忆以后关上的tab信息 var lastTabList = JSON.parse(sessionStorage.getItem("lastTabList")); var id = $(e).parent().attr("id"); if (!lastTabList) { sessionStorage.setItem( "lastTabList", JSON.stringify([ { id: id, text: $(e).find(".fontColor").text(), url: url }, ]) ); } else { var arridx = lastTabList.some(function (i) { return i.id === id; }); if (!arridx) { lastTabList.push({ id: id, text: $(e).find(".fontColor").text(), url: url, }); } sessionStorage.setItem("lastTabList", JSON.stringify(lastTabList)); } //点击后新增tab element.tabDelete(crrentTabName, reportName); element.tabAdd(crrentTabName, { title: $(e).find(".fontColor").text(), content: '<iframe src="./' + url + '" width="100%" height="100%' + '" scrolling="no" marginheight="0" marginwidth="0"></iframe>', //反对传入html id: reportName, }); element.tabChange(crrentTabName, reportName); }; //tab切换 element.on("tab(mainTab)", function (data) { if ($(".layui-show iframe").attr("src")) { var url = $(".layui-show iframe").attr("src").slice(2); sessionStorage.setItem("url", url); } sessionStorage.setItem("activeMenuId", $(this).attr("lay-id")); }); //tab删除 element.on("tabDelete(mainTab)", function (data) { var delId = $(this).parent().attr("lay-id"); var lastTabList = JSON.parse(sessionStorage.getItem("lastTabList")); lastTabList.forEach(function (i, idx) { //删除对于记忆的tab项 console.log(i.id, delId); if (i.id === delId) { lastTabList.splice(idx, 1); } }); sessionStorage.setItem("lastTabList", JSON.stringify(lastTabList)); }); if (sessionStorage.getItem("lastTabList")) { //把记忆的tab全副创立进去 var crrentTabName = $(".layui-tab.active").attr("lay-filter"); var lastTabList = JSON.parse(sessionStorage.getItem("lastTabList")); lastTabList.forEach(function (i) { element.tabAdd(crrentTabName, { title: i.text, content: '<iframe src="./' + i.url + '" width="100%" height="100%" scrolling="no" marginheight="0" marginwidth="0"></iframe>', //反对传入html id: i.id, }); }); } element.tabChange( $(".layui-tab.active").attr("lay-filter"), sessionStorage.getItem("activeMenuId") ); }); if (sessionStorage.getItem("activeMenuId")) { $("#main-menu > #" + sessionStorage.getItem("activeMenuId")).addClass( "selected" ); //高亮一级 } else { $(".homePage_1").addClass("selected"); } //页面加载实现后调整主体高度 $(".body-main").css( "height", "calc(100% - " + ($(".main-top").outerHeight() + $(".main-header").outerHeight() + 30) + "px)" ); $("#home").height( $(".body-main").height() - $(".body-main .layui-tab-title").outerHeight() );
剩下其余的就是一些款式调整和默认selected
storage的存储状况:
以下是二级菜单的构造,应用layui的导航组件为例:
<body> <div class="body-left"> <div class="left-nav"> <ul class="layui-nav layui-nav-tree layui-inline " lay-filter="leftnav"> <li id="f21c3279e67448d1a5a96d376b3695f6" class="layui-nav-item UserManage" ><a href="#" onclick="changeUrlSec('BasicSet/UserManage/index.html', 'UserManage')"> 用户治理</a></li> <li id="4145cd3cde9740bb9bec57ec9bfba31a" class="layui-nav-item UserAuthorization" ><a href="#" onclick="changeUrlSec('BasicSet/UserAuthorization/index.html', 'UserAuthorization')">用户角色</a></li> <li class="layui-nav-item version" ><a href="#" onclick="changeUrlSec('BasicSet/index.html', 'version')">版本更新</a></li> </ul> </div> </div> <div class="left-button layui-icon layui-icon-left" ></div> <div class="body-main"> <iframe id="Iframe" width="100%" height="100%" scrolling="no" marginheight="0" src="./UserManage/index.html" marginwidth="0"></iframe> </div></body>
这里的话就比较简单,存储对应二级页面的文件夹名,而后在下次关上时间接设置视图的src对记忆页面进行显示。
window.changeUrlSec = function (url, className) { var currtMenu = url.slice(0, url.indexOf("/")) + "/"; if (window.location.pathname.indexOf(currtMenu) > -1) { sessionStorage.setItem("className", className); } var ss = window.location.href.indexOf("/html/"); var aa = window.location.href.substr(0, ss + 6); url = aa + url.split("/")[0]; console.log(url); document.getElementById("Iframe") && (document.getElementById("Iframe").src = url + "/" + className + "/index.html"); //跳转动作 }; var url = sessionStorage.getItem("url"); var currtMenu = url.slice(0, url.indexOf("/")) + "/"; if ( sessionStorage.getItem("className") !== "null" && window.location.pathname.indexOf(currtMenu) > -1 //与记忆的url合乎才进行跳转 ) { //记忆上次停留菜单 $("." + sessionStorage.getItem("className")).addClass("layui-this"); if (url) { changeUrlSec(url, sessionStorage.getItem("className")); } } else { //如上次菜单不匹配则默认第一个选中 $(".layui-nav > .layui-nav-item:first-child").addClass("layui-this"); }});