You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建含可拖动拆分器的响应式HTML Div?并实现标准页头/内容/页脚页面

实现带可拖动拆分器的响应式页眉/内容/页脚布局

我来帮你搞定这个布局需求!结合你提到的标准页眉/内容/页脚结构,我整理了一个完整的实现方案,包含可拖动的面板拆分器,同时保证整体在不同屏幕尺寸下的响应式适配。

完整实现代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>可拖动拆分器布局</title>
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.14/semantic.min.css">
    <style>
        /* 全局重置和基础布局 */
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        /* 页面容器:垂直flex布局,确保页脚在底部 */
        .page-container {
            display: flex;
            flex-direction: column;
            min-height: 100vh;
        }

        /* 页眉样式 */
        .page-header {
            padding: 1rem;
            background-color: #2c3e50;
            color: white;
            text-align: center;
        }

        /* 内容区域:填充页眉和页脚之外的空间 */
        .content-area {
            flex: 1;
            display: flex;
            flex-direction: row;
            overflow: hidden;
            touch-action: none; /* 防止触摸设备默认行为干扰拖动 */
        }

        /* 左侧面板 */
        .panel-left {
            flex: 0 0 300px; /* 初始宽度300px */
            min-width: 200px; /* 最小宽度限制 */
            max-width: calc(100% - 200px); /* 最大宽度限制 */
            background-color: #ecf0f1;
            padding: 1rem;
            overflow: auto;
        }

        /* 拆分器样式 */
        .splitter {
            flex: 0 0 8px;
            background-color: #bdc3c7;
            cursor: col-resize;
            position: relative;
        }

        /* 拆分器悬停效果 */
        .splitter:hover {
            background-color: #95a5a6;
        }

        /* 右侧面板 */
        .panel-right {
            flex: 1; /* 自动填充剩余空间 */
            background-color: #ffffff;
            padding: 1rem;
            overflow: auto;
        }

        /* 页脚样式 */
        .page-footer {
            padding: 1rem;
            background-color: #2c3e50;
            color: white;
            text-align: center;
        }

        /* 响应式适配:小屏幕转为垂直布局 */
        @media (max-width: 768px) {
            .content-area {
                flex-direction: column;
            }

            .panel-left {
                flex: 0 0 200px;
                min-width: 100%;
                max-width: 100%;
            }

            .splitter {
                flex: 0 0 8px;
                cursor: row-resize;
            }
        }
    </style>
</head>
<body>
    <div class="page-container">
        <!-- 页眉 -->
        <header class="page-header">
            <h1>页面页眉</h1>
        </header>

        <!-- 内容区域(带拆分器) -->
        <div class="content-area">
            <div class="panel-left">
                <h3>左侧面板</h3>
                <p>这里是左侧可拖动调整宽度的面板内容...</p>
                <p>可以添加更多内容测试滚动效果</p>
            </div>
            <div class="splitter" id="splitter"></div>
            <div class="panel-right">
                <h3>右侧面板</h3>
                <p>这里是右侧自动填充剩余空间的面板内容...</p>
                <p>当拖动中间的拆分器时,两侧面板的宽度会动态调整</p>
            </div>
        </div>

        <!-- 页脚 -->
        <footer class="page-footer">
            <p>页面页脚</p>
        </footer>
    </div>

    <script>
        // 初始化拆分器功能
        document.addEventListener('DOMContentLoaded', function() {
            const splitter = document.getElementById('splitter');
            const panelLeft = document.querySelector('.panel-left');
            let isDragging = false;
            let startX, startWidth;

            // 鼠标按下事件
            splitter.addEventListener('mousedown', startDrag);
            // 触摸开始事件(适配移动端)
            splitter.addEventListener('touchstart', startDrag, { passive: false });

            // 开始拖动
            function startDrag(e) {
                isDragging = true;
                // 记录初始位置和面板宽度
                startX = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX;
                startWidth = parseInt(window.getComputedStyle(panelLeft).width);

                // 添加事件监听
                document.addEventListener('mousemove', drag);
                document.addEventListener('touchmove', drag, { passive: false });
                document.addEventListener('mouseup', stopDrag);
                document.addEventListener('touchend', stopDrag);

                // 防止文本选中干扰
                e.preventDefault();
            }

            // 拖动过程
            function drag(e) {
                if (!isDragging) return;

                const currentX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
                const deltaX = currentX - startX;
                const newWidth = startWidth + deltaX;

                // 应用新宽度,同时限制在最小和最大值之间
                panelLeft.style.width = `${Math.max(200, Math.min(newWidth, window.innerWidth - 200))}px`;
            }

            // 停止拖动
            function stopDrag() {
                isDragging = false;
                // 移除事件监听
                document.removeEventListener('mousemove', drag);
                document.removeEventListener('touchmove', drag);
                document.removeEventListener('mouseup', stopDrag);
                document.removeEventListener('touchend', stopDrag);
            }
        });
    </script>
</body>
</html>

关键细节说明

1. 整体布局逻辑

  • 外层.page-container使用flex-direction: column和min-height: 100vh,确保页面占满整个视口,同时让页眉和页脚固定在顶部和底部,中间的内容区自动填充剩余空间
  • .content-area设置flex: 1,负责承载可拆分的左右面板,内部用flex-direction: row实现水平布局

2. 可拖动拆分器实现

  • 拆分器.splitter设置固定宽度,通过cursor: col-resize提示用户可拖动
  • JavaScript部分通过监听鼠标和触摸事件,记录拖动过程中的位置变化,动态调整左侧面板的宽度,同时设置了最小和最大宽度限制,避免面板被拖到不可用的状态
  • 加入touch-action: none和触摸事件监听,确保在移动端也能正常拖动

3. 响应式适配

  • 使用媒体查询@media (max-width: 768px),在小屏幕设备上自动将内容区的布局转为垂直方向,拆分器的鼠标样式也改为row-resize,适配垂直拖动的场景

你可以直接复制这段代码运行,测试拖动效果和响应式表现,也可以根据自己的需求调整面板的初始宽度、最小/最大宽度以及样式细节。

内容的提问来源于stack exchange,提问作者James Fremen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:34:26