mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-11-07 19:40:49 +08:00
新增全部模块顶部面板与星标收藏
This commit is contained in:
@@ -1022,4 +1022,9 @@
|
||||
|
||||
.layuimini-star.layuimini-star-active {
|
||||
color: #ffb800;
|
||||
}
|
||||
|
||||
/* 面板打开期间收起「更多」hover 下拉(临时类由 openModulePanel/closeModulePanel 维护) */
|
||||
.layuimini-header-more-panelopen > .layui-nav-child {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -8,6 +8,9 @@
|
||||
// 菜单数据缓存(renderMultiModule 入口保存,收藏过滤与面板渲染复用;保存原 menuList 引用)
|
||||
menuData: [],
|
||||
|
||||
// 顶部「全部模块」面板 layer index(null=面板未打开)
|
||||
modulePanelIndex: null,
|
||||
|
||||
/**
|
||||
* 菜单初始化
|
||||
* @param options.menuList 菜单数据信息
|
||||
@@ -238,6 +241,26 @@
|
||||
miniMenu.syncHeaderActiveState();
|
||||
},
|
||||
|
||||
/**
|
||||
* 头部模块 DOM 重排:头部 li 显示顺序跟随 sortModules(收藏置顶+原序回填),「更多」li 常驻末尾
|
||||
* 星标收藏切换后调用实现头部即时重排;移动 li 不改类名,激活态/折叠态由后续 relayout 重算
|
||||
*/
|
||||
reorderHeaderMenu: function () {
|
||||
var $headerMenu = $('.layuimini-menu-header-pc');
|
||||
var $more = $headerMenu.children('.layuimini-header-more');
|
||||
if (!$headerMenu.length || !$more.length) {
|
||||
return;
|
||||
}
|
||||
var sortedMenuList = miniMenu.sortModules(miniMenu.menuData);
|
||||
var moreEl = $more[0];
|
||||
miniMenu.each(sortedMenuList, function (index, menu) {
|
||||
var li = document.getElementById('multi_module_' + miniMenu.menuData.indexOf(menu) + 'HeaderId');
|
||||
if (li) {
|
||||
$headerMenu[0].insertBefore(li, moreEl); //依次前插到「更多」li 之前,形成排序后顺序
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 头部模块宽度自适应折叠重算:累计宽度超出可用宽度的模块收纳进「更多」下拉
|
||||
*/
|
||||
@@ -300,6 +323,64 @@
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 顶部「全部模块」面板打开:menuData 经 sortModules 平铺为 tile(收藏置顶+回填序)
|
||||
*/
|
||||
openModulePanel: function () {
|
||||
var me = this;
|
||||
var favorites = me.getFavorites();
|
||||
var sortedMenuList = me.sortModules(me.menuData);
|
||||
var tileHtml = '';
|
||||
me.each(sortedMenuList, function (index, menu) {
|
||||
// data-header-id 按 menuList 原下标映射(排序只影响显示顺序,与头部 li id 分配规则一致);不带 data-menu,避免与 [data-menu] 委托双触发
|
||||
var originalIndex = me.menuData.indexOf(menu);
|
||||
var starActive = favorites.indexOf(menu.title) !== -1 ? ' layuimini-star-active' : '';
|
||||
var icon = menu.icon ? menu.icon : '';
|
||||
tileHtml += '<div class="layuimini-module-panel-item" data-header-id="multi_module_' + originalIndex + 'HeaderId" data-title="' + menu.title + '">' +
|
||||
'<i class="' + icon + '"></i>' +
|
||||
'<div>' + menu.title + '</div>' +
|
||||
'<span class="layuimini-star fa fa-star-o' + starActive + '"></span>' +
|
||||
'</div>';
|
||||
});
|
||||
// 配色继承:非透明头部主题时同步头部背景/字色到面板根容器;透明主题(rgba(0,0,0,0))保留 CSS 白底深字兜底
|
||||
var panelStyle = '';
|
||||
var headerEl = $('.layui-header').first()[0];
|
||||
if (headerEl) {
|
||||
var headerStyle = getComputedStyle(headerEl);
|
||||
if (headerStyle.backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
||||
panelStyle = ' style="background-color:' + headerStyle.backgroundColor + ';color:' + headerStyle.color + ';"';
|
||||
}
|
||||
}
|
||||
// 打开期间收起「更多」hover 下拉,避免遮罩后方残留展开外观(关闭时移除)
|
||||
$('.layuimini-header-more').addClass('layuimini-header-more-panelopen');
|
||||
me.modulePanelIndex = layer.open({
|
||||
type: 1,
|
||||
title: '全部模块',
|
||||
anim: 2,
|
||||
offset: 't',
|
||||
area: ['100%', 'auto'],
|
||||
shade: 0.2,
|
||||
shadeClose: true,
|
||||
closeBtn: 0,
|
||||
content: '<div class="layuimini-module-panel"' + panelStyle + '><div class="layuimini-module-panel-grid">' + tileHtml + '</div></div>',
|
||||
end: function () {
|
||||
me.closeModulePanel(); //遮罩/切tile等 layer 原生关闭路径统一走清理
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 顶部面板关闭:幂等(end 回调重入时 index 已置 null,重复调用安全)
|
||||
*/
|
||||
closeModulePanel: function () {
|
||||
var index = miniMenu.modulePanelIndex;
|
||||
miniMenu.modulePanelIndex = null;
|
||||
if (index) {
|
||||
layer.close(index);
|
||||
}
|
||||
$('.layuimini-header-more').removeClass('layuimini-header-more-panelopen');
|
||||
},
|
||||
|
||||
/**
|
||||
* 轻量防抖:delay 内重复触发只执行最后一次
|
||||
*/
|
||||
@@ -404,6 +485,41 @@
|
||||
setTimeout(miniMenu.relayoutHeaderMenu, 260); //左侧布局带 .2s 过渡,同步测量会读到中间值,等过渡结束再重算
|
||||
layer.close(loading);
|
||||
});
|
||||
|
||||
/**
|
||||
* 顶部「全部模块」面板:委托绑定一次即可(tile/星标均为动态 DOM,重渲染无需重绑)
|
||||
*/
|
||||
if (!miniMenu._panelListenerBound) {
|
||||
miniMenu._panelListenerBound = true;
|
||||
// 打开/切换面板:「更多」li 自身不带 data-menu,stopPropagation 隔离其他 body 委托
|
||||
$('body').on('click', '.layuimini-header-more > a', function (e) {
|
||||
e.stopPropagation();
|
||||
if (miniMenu.modulePanelIndex) {
|
||||
miniMenu.closeModulePanel();
|
||||
} else {
|
||||
miniMenu.openModulePanel();
|
||||
}
|
||||
});
|
||||
// ESC 关闭面板(layui layer 原生不支持 ESC,自实现;仅在面板存在时响应,不影响其他弹层)
|
||||
$(document).on('keydown', function (e) {
|
||||
if (e.keyCode === 27 && miniMenu.modulePanelIndex) {
|
||||
miniMenu.closeModulePanel();
|
||||
}
|
||||
});
|
||||
// tile 主体点击:触发真实头部 li(可见或折叠隐藏均可),走 [data-menu] 委托完整链路后关闭面板
|
||||
$('body').on('click', '.layuimini-module-panel-item', function () {
|
||||
$('#' + $(this).attr('data-header-id')).trigger('click');
|
||||
layer.close(miniMenu.modulePanelIndex);
|
||||
});
|
||||
// 星标点击:切换收藏 → 头部即时重排(重排序+折叠重算)→ 就地更新星标类名(面板保持打开,支持连续操作)
|
||||
$('body').on('click', '.layuimini-module-panel-item .layuimini-star', function (e) {
|
||||
e.stopPropagation(); //阻断冒泡,避免同时触发 tile 的切模块点击
|
||||
var isAdd = miniMenu.toggleFavorite($(this).closest('.layuimini-module-panel-item').attr('data-title'));
|
||||
miniMenu.reorderHeaderMenu();
|
||||
miniMenu.relayoutHeaderMenu();
|
||||
$(this).toggleClass('layuimini-star-active', isAdd);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user