class TabsContainer extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.openTabs = new Set();
this.currentActiveTabId = null; // 跟踪当前激活的标签页ID
}
connectedCallback() {
this.render();
this.setupEventListeners();
}
render() {
this.shadowRoot.innerHTML = `
`;
}
setupEventListeners() {
const tabsHeader = this.shadowRoot.querySelector('.tabs-header');
const scrollLeftBtn = this.shadowRoot.getElementById('scrollLeft');
const scrollRightBtn = this.shadowRoot.getElementById('scrollRight');
// 检查是否需要显示滚动按钮
const checkScrollButtons = () => {
const { scrollLeft, scrollWidth, clientWidth } = tabsHeader;
const hasScroll = scrollWidth > clientWidth;
scrollLeftBtn.classList.toggle('show', hasScroll && scrollLeft > 0);
scrollRightBtn.classList.toggle('show', hasScroll && scrollLeft < scrollWidth - clientWidth - 1);
};
// 添加滚动事件监听
tabsHeader.addEventListener('scroll', checkScrollButtons);
window.addEventListener('resize', checkScrollButtons);
// 滚动按钮点击事件
scrollLeftBtn.addEventListener('click', () => {
tabsHeader.scrollBy({ left: -200, behavior: 'smooth' });
});
scrollRightBtn.addEventListener('click', () => {
tabsHeader.scrollBy({ left: 200, behavior: 'smooth' });
});
// 添加 MutationObserver 监听标签页的变化
const observer = new MutationObserver(checkScrollButtons);
observer.observe(tabsHeader, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class']
});
// 初始检查滚动按钮状态
checkScrollButtons();
}
activateTab(id) {
const activeTab = this.shadowRoot.querySelector(`.tab[data-tab="${id}"]`);
if (!activeTab) return;
// 检查是否是当前已激活的标签页,如果是则不触发事件
if (this.currentActiveTabId === id) {
return;
}
// 记录新的激活标签页ID
const previousTabId = this.currentActiveTabId;
this.currentActiveTabId = id;
this.shadowRoot.querySelectorAll('.tab').forEach(tab => {
tab.classList.toggle('active', tab.getAttribute('data-tab') === id);
});
const title = activeTab.getAttribute('data-title') || activeTab.querySelector('span').textContent;
const parentText = activeTab.getAttribute('data-parent-text') || '主页';
const parentTool = activeTab.getAttribute('data-parent-tool');
// 触发标签页激活事件,并传递前一个标签页ID
this.dispatchEvent(new CustomEvent('tab-activated', {
detail: {
id,
title,
parentText,
parentTool,
previousTabId, // 添加前一个标签页ID
isTabSwitch: true // 标记为真正的标签切换
}
}));
// 同步左侧子工具栏选中状态
if (parentTool) {
// 先选中主工具栏
const mainToolbar = document.querySelector('main-toolbar');
const mainToolItem = mainToolbar.shadowRoot.querySelector(`.tool-item[data-tool="${parentTool}"]`);
if (mainToolItem) {
// 移除所有工具项的激活状态
mainToolbar.shadowRoot.querySelectorAll('.tool-item').forEach(t => t.classList.remove('active'));
// 激活当前工具项
mainToolItem.classList.add('active');
}
// 再同步子工具栏
const subToolbar = document.querySelector('sub-toolbar');
subToolbar.setAttribute('current-tool', parentTool);
// 找到并点击对应的子菜单项
setTimeout(() => {
const subMenuItems = subToolbar.shadowRoot.querySelectorAll('.sub-item');
const targetSubItem = Array.from(subMenuItems).find(item =>
item.textContent.trim() === title &&
item.closest('.sub-menu').getAttribute('data-parent') === parentTool
);
if (targetSubItem) {
// 移除所有子菜单项的激活状态
subMenuItems.forEach(item => item.classList.remove('active'));
// 激活当前子菜单项
targetSubItem.classList.add('active');
}
}, 0); // 使用setTimeout确保DOM已更新
}
}
createTab(id, title, icon, parentText, parentTool) {
// 对于其他标签页,如果已经打开则激活
if (this.openTabs.has(id)) {
this.activateTab(id);
return;
}
const tab = document.createElement('div');
tab.className = 'tab';
tab.setAttribute('data-tab', id);
tab.setAttribute('data-parent-text', parentText || '主页');
tab.setAttribute('data-parent-tool', parentTool || 'home');
tab.setAttribute('data-title', title);
tab.innerHTML = `
${title}
${id !== 'overview' ? '' : ''}
`;
this.shadowRoot.querySelector('.tabs-header').appendChild(tab);
tab.addEventListener('click', () => {
this.activateTab(id);
});
if (id !== 'overview') {
const closeBtn = tab.querySelector('.close-tab');
closeBtn.addEventListener('click', (e) => {
e.stopPropagation();
this.closeTab(id);
});
}
this.openTabs.add(id);
this.activateTab(id);
}
closeTab(id) {
if (id === 'overview') return;
const tab = this.shadowRoot.querySelector(`.tab[data-tab="${id}"]`);
if (tab.classList.contains('active')) {
const prevTab = tab.previousElementSibling || tab.nextElementSibling;
if (prevTab) {
this.activateTab(prevTab.getAttribute('data-tab'));
}
}
tab.remove();
this.openTabs.delete(id);
// 触发标签页关闭事件
this.dispatchEvent(new CustomEvent('tab-closed', {
detail: { id }
}));
}
}
customElements.define('tabs-container', TabsContainer);