新增全部模块顶部面板与星标收藏

This commit is contained in:
augushong
2026-10-10 14:26:51 +00:00
parent 39c882ac16
commit 58ef1bbc64
2 changed files with 121 additions and 0 deletions

View File

@@ -1022,4 +1022,9 @@
.layuimini-star.layuimini-star-active {
color: #ffb800;
}
/* 面板打开期间收起「更多」hover 下拉(临时类由 openModulePanel/closeModulePanel 维护) */
.layuimini-header-more-panelopen > .layui-nav-child {
display: none !important;
}

View File

@@ -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);
});
}
},
};