多标签页导航后台模板 html+css+js 纯手写 无第三方UI框架 复制粘贴即用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多标签页导航管理系统</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: Arial, sans-serif;
        }

        body {
            display: flex;
            height: 100vh;
            overflow: hidden;
            flex-direction: column;
        }

        /* 侧边栏样式 */
        .sidebar {
            width: 220px;
            background-color: #2c3e50;
            color: white;
            transition: transform 0.3s ease;
            z-index: 10;
            overflow-y: auto;
            height: 100%;
        }

        .sidebar-header {
            padding: 20px;
            font-size: 18px;
            font-weight: bold;
            border-bottom: 1px solid #34495e;
        }

        /* 导航分组样式 */
        .nav-group {
            margin: 10px 0;
        }

        .group-title {
            padding: 15px 20px;
            font-weight: bold;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            align-items: center;
            background-color: #34495e;
        }

            .group-title .arrow {
                transition: transform 0.3s ease;
            }

            .group-title.expanded .arrow {
                transform: rotate(90deg);
            }

        /* 子菜单样式 */
        .submenu {
            list-style: none;
            display: none; /* 默认隐藏子菜单 */
            background-color: #2c3e50;
        }

            .submenu.show {
                display: block; /* 显示子菜单 */
            }

            .submenu li a {
                display: block;
                padding: 12px 35px; /* 缩进显示层级 */
                color: #bdc3c7;
                text-decoration: none;
                transition: all 0.3s;
            }

                .submenu li a:hover,
                .submenu li a.active {
                    background-color: #1abc9c;
                    color: white;
                }

        /* 主内容区 */
        .main-container {
            display: flex;
            flex: 1;
            overflow: hidden;
        }

        .main-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        /* 顶部导航 */
        .top-nav {
            height: 60px;
            background-color: #3498db;
            color: white;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 20px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }

        .menu-toggle {
            cursor: pointer;
            font-size: 20px;
        }

        .user-info {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        /* 标签页样式 */
        .tabs-container {
            height: 40px;
            background-color: #f8f9fa;
            border-bottom: 1px solid #ddd;
            display: flex;
            align-items: center;
            overflow-x: auto;
            white-space: nowrap;
        }

        .tab {
            display: inline-flex;
            align-items: center;
            padding: 0 15px;
            height: 100%;
            background-color: #fff;
            border-right: 1px solid #ddd;
            cursor: pointer;
            transition: background-color 0.2s;
        }

            .tab.active {
                background-color: #e9ecef;
                border-bottom: 2px solid #3498db;
            }

        .tab-title {
            margin-right: 8px;
        }

        .tab-close {
            width: 16px;
            height: 16px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 12px;
            transition: background-color 0.2s;
        }

            .tab-close:hover {
                background-color: #eee;
            }

        /* iframe 内容区域 */
        .iframe-container {
            flex: 1;
            overflow: hidden;
            position: relative;
        }

        .iframe-page {
            width: 100%;
            height: 100%;
            border: none;
            position: absolute;
            top: 0;
            left: 0;
            display: none;
        }

            .iframe-page.active {
                display: block;
            }

        /* 移动端适配 */
        .media (max-width: 768px) {
            .sidebar

        {
            position: absolute;
            height: 100%;
            transform: translateX(-100%);
        }

        .sidebar.show {
            transform: translateX(0);
        }

        .tabs-container {
            height: 36px;
        }

        }
    </style>
</head>
<body>
    <div class="main-container">
        <!-- 侧边栏导航(两层结构) -->
        <div class="sidebar" id="sidebar">
            <div class="sidebar-header">管理系统</div>

            <!-- 第一个分组 -->
            <div class="nav-group">
                <div class="group-title expanded" data-group="dashboard-group">
                    <span>控制台</span>
                    <span class="arrow">▶</span>
                </div>
                <ul class="submenu show" id="dashboard-group">
                    <li><a class="active" href="javascript:;" data-src="dashboard.html" data-title="仪表盘" data-id="dashboard">仪表盘</a></li>
                    <li><a href="javascript:;" data-src="statistics.html" data-title="数据统计" data-id="statistics">数据统计</a></li>
                </ul>
            </div>

            <!-- 第二个分组 -->
            <div class="nav-group">
                <div class="group-title" data-group="user-group">
                    <span>用户管理</span>
                    <span class="arrow">▶</span>
                </div>
                <ul class="submenu" id="user-group">
                    <li><a href="javascript:;" data-src="users/list.html" data-title="用户列表" data-id="user-list">用户列表</a></li>
                    <li><a href="javascript:;" data-src="users/add.html" data-title="添加用户" data-id="user-add">添加用户</a></li>
                    <li><a href="javascript:;" data-src="users/roles.html" data-title="角色权限" data-id="user-roles">角色权限</a></li>
                </ul>
            </div>

            <!-- 第三个分组 -->
            <div class="nav-group">
                <div class="group-title" data-group="product-group">
                    <span>产品管理</span>
                    <span class="arrow">▶</span>
                </div>
                <ul class="submenu" id="product-group">
                    <li><a href="javascript:;" data-src="products/list.html" data-title="产品列表" data-id="product-list">产品列表</a></li>
                    <li><a href="javascript:;" data-src="products/categories.html" data-title="产品分类" data-id="product-cate">产品分类</a></li>
                </ul>
            </div>

            <!-- 第四个分组 -->
            <div class="nav-group">
                <div class="group-title" data-group="system-group">
                    <span>系统设置</span>
                    <span class="arrow">▶</span>
                </div>
                <ul class="submenu" id="system-group">
                    <li><a href="javascript:;" data-src="settings/basic.html" data-title="基本设置" data-id="setting-basic">基本设置</a></li>
                    <li><a href="javascript:;" data-src="settings/logs.html" data-title="操作日志" data-id="setting-log">操作日志</a></li>
                    <li><a href="javascript:;" data-src="https://www.baidu.com" data-title="外部链接" data-id="external-link">百度搜索</a></li>
                </ul>
            </div>
        </div>

        <!-- 主内容区域 -->
        <div class="main-content">
            <!-- 顶部导航栏 -->
            <div class="top-nav">
                <div class="menu-toggle" id="menuToggle">☰</div>
                <div class="user-info">
                    <span>管理员</span>
                </div>
            </div>

            <!-- 标签页容器 -->
            <div class="tabs-container" id="tabsContainer">
                <!-- 标签页会动态生成在这里 -->
            </div>

            <!-- iframe 容器 -->
            <div class="iframe-container" id="iframeContainer">
                <!-- iframe 页面会动态生成在这里 -->
            </div>
        </div>
    </div>

    <script>
        // 获取DOM元素
        const sidebar = document.getElementById('sidebar');
        const menuToggle = document.getElementById('menuToggle');
        const groupTitles = document.querySelectorAll('.group-title');
        const submenuLinks = document.querySelectorAll('.submenu a');
        const tabsContainer = document.getElementById('tabsContainer');
        const iframeContainer = document.getElementById('iframeContainer');

        // 存储打开的页面信息
        let openedPages = [];
        let activePageId = '';

        // 初始化 - 打开默认页面
        function init() {
            const defaultLink = document.querySelector('.submenu a.active');
            if (defaultLink) {
                openPage(defaultLink);
            }
        }

        // 侧边栏切换
        menuToggle.addEventListener('click', () => {
            sidebar.classList.toggle('show');
        });

        // 分组标题点击事件(展开/折叠子菜单)
        groupTitles.forEach(title => {
            title.addEventListener('click', () => {
                const groupId = title.getAttribute('data-group');
                const submenu = document.getElementById(groupId);

                // 切换当前分组的展开状态
                title.classList.toggle('expanded');
                submenu.classList.toggle('show');
            });
        });

        // 打开页面
        function openPage(link) {
            const pageId = link.getAttribute('data-id');
            const pageTitle = link.getAttribute('data-title');
            const pageSrc = link.getAttribute('data-src');

            // 检查页面是否已打开
            const existingPage = openedPages.find(page => page.id === pageId);

            if (existingPage) {
                // 如果已打开,切换到该页面
                switchToPage(pageId);
                return;
            }

            // 添加到打开的页面列表
            openedPages.push({
                id: pageId,
                title: pageTitle,
                src: pageSrc
            });

            // 创建标签页
            createTab(pageId, pageTitle);

            // 创建iframe
            createIframe(pageId, pageSrc);

            // 切换到新页面
            switchToPage(pageId);

            // 更新激活状态
            updateActiveLink(pageId);

            // 移动端自动关闭侧边栏
            if (window.innerWidth <= 768) {
                sidebar.classList.remove('show');
            }
        }

        // 创建标签页
        function createTab(pageId, title) {
            const tab = document.createElement('div');
            tab.className = 'tab';
            tab.dataset.id = pageId;
            tab.innerHTML = `
                <span class="tab-title">${title}</span>
                <span class="tab-close">×</span>
            `;

            // 标签点击事件
            tab.addEventListener('click', (e) => {
                if (!e.target.classList.contains('tab-close')) {
                    switchToPage(pageId);
                }
            });

            // 关闭按钮点击事件
            tab.querySelector('.tab-close').addEventListener('click', (e) => {
                e.stopPropagation();
                closePage(pageId);
            });

            tabsContainer.appendChild(tab);
        }

        // 创建iframe
        function createIframe(pageId, src) {
            const iframe = document.createElement('iframe');
            iframe.className = 'iframe-page';
            iframe.dataset.id = pageId;
            iframe.src = src;
            iframeContainer.appendChild(iframe);
        }

        // 切换到指定页面
        function switchToPage(pageId) {
            // 移除所有标签和iframe的激活状态
            document.querySelectorAll('.tab').forEach(tab => {
                tab.classList.remove('active');
            });
            document.querySelectorAll('.iframe-page').forEach(iframe => {
                iframe.classList.remove('active');
            });

            // 设置当前页面为激活状态
            document.querySelector(`.tab[data-id="${pageId}"]`).classList.add('active');
            document.querySelector(`.iframe-page[data-id="${pageId}"]`).classList.add('active');

            // 更新当前激活页面ID
            activePageId = pageId;

            // 更新侧边栏链接激活状态
            updateActiveLink(pageId);
        }

        // 关闭页面
        function closePage(pageId) {
            // 如果关闭的是当前激活页面,需要切换到其他页面
            if (pageId === activePageId) {
                const currentIndex = openedPages.findIndex(page => page.id === pageId);
                // 尝试切换到前一个页面,如果没有则切换到后一个
                let newIndex = currentIndex > 0 ? currentIndex - 1 : currentIndex + 1;

                if (openedPages[newIndex]) {
                    switchToPage(openedPages[newIndex].id);
                }
            }

            // 从列表中移除
            openedPages = openedPages.filter(page => page.id !== pageId);

            // 移除标签和iframe
            const tab = document.querySelector(`.tab[data-id="${pageId}"]`);
            const iframe = document.querySelector(`.iframe-page[data-id="${pageId}"]`);

            if (tab) tab.remove();
            if (iframe) iframe.remove();
        }

        // 更新侧边栏链接激活状态
        function updateActiveLink(pageId) {
            submenuLinks.forEach(link => {
                link.classList.remove('active');
                if (link.getAttribute('data-id') === pageId) {
                    link.classList.add('active');
                }
            });
        }

        // 子菜单链接点击事件(打开或切换页面)
        submenuLinks.forEach(link => {
            link.addEventListener('click', () => {
                openPage(link);
            });
        });

        // 初始化页面
        init();
    </script>
</body>
</html>

这是基于: 极简后台模板 HTML+CSS+JS 纯手写 无第三方UI框架 复制粘贴即用 做了修改....


主要修改内容说明:

  1. 新增了标签页容器 (.tabs-container),用于显示顶部标签页

  2. 修改了内容区域结构,使用多个 iframe 实现多页面同时加载

  3. 添加了页面管理逻辑,包括:

    • 打开新页面(已打开则切换)
    • 切换标签页
    • 关闭标签页
    • 标签页与侧边栏联动
  4. 核心功能特点:

    • 点击侧边栏菜单会在顶部创建对应标签页
    • 已打开的页面再次点击会直接切换
    • 可通过标签页右上角关闭按钮关闭页面
    • 关闭当前页面会自动切换到其他页面
    • 侧边栏链接会与当前激活页面保持同步
  5. 保留了原有的响应式设计,在移动设备上仍可正常使用

您可以根据实际需求进一步调整样式和交互细节,比如添加标签页右键菜单、标签页拖拽排序等高级功能。


相关推荐
Hilaku2 小时前
别再吹性能优化了:你的应用卡顿,纯粹是因为产品设计烂🤷‍♂️
前端·javascript·代码规范
驯狼小羊羔2 小时前
学习随笔-hooks和mixins
前端·javascript·vue.js·学习·hooks·mixins
风止何安啊3 小时前
JS 对象:从 “散装” 到 “精装” 的晋级之路
前端·javascript·node.js
Achieve前端实验室3 小时前
【每日一面】如何解决内存泄漏
前端·javascript·面试
肥猪大大3 小时前
Rsbuild迁移之node-sass引发的血案
前端·javascript
嬉皮客4 小时前
Gird布局详解
前端·css
Moment5 小时前
专为 LLM 设计的数据格式 TOON,可节省 60% Token
前端·javascript·后端
G***66915 小时前
前端性能优化插件,CSS与JavaScript压缩插件实战指南
前端·javascript·css
鹏多多6 小时前
React的useRef的深度解析与应用指南
前端·javascript·react.js