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} ${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);