源于沸点求助
原文: 求助一个问题,如果我想让页面横向滚动时,div1和div3固定,div2和div4绑定在一起移动,纵向滚动时,div1和div2固定,div3和div4绑定在一起滚动
<!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>
/* --- 基础页面样式 --- */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
/* 禁止 body 自身的滚动条,所有滚动都在 grid 容器内处理 */
overflow: hidden;
}

/* --- 主要网格容器 --- */
.grid-container {
/* 使用 CSS Grid 来创建一个 2x2 的布局 */
display: grid;
/* 定义网格布局:
- grid-template-columns: 定义两列。第一列固定宽度 150px,第二列占据剩余所有空间 (1fr)。
- grid-template-rows: 定义两行。第一行固定高度 60px,第二行占据剩余所有空间 (1fr)。
*/
grid-template-columns: 150px 1fr;
grid-template-rows: 60px 1fr;
/* 让网格容器占满整个视口 */
width: 100vw;
height: 100vh;
}
/* --- 所有四个 div 的通用样式 --- */
.grid-item {
border-right: 1px solid #dcdcdc;
border-bottom: 1px solid #dcdcdc;
box-sizing: border-box; /* 确保边框和内边距不会增加元素的尺寸 */
}
.content-wrapper {
display: flex;
align-items: center;
justify-content: center;
}
/* --- 四个区域的特定样式和行为 --- */
/* div1: 左上角固定区域 */
#div1 {
background-color: #f5f5f5;
z-index: 3; /* z-index 最高,确保它显示在所有滚动内容的上面 */
font-weight: bold;
}
/* div2: 顶部标题行 (只横向滚动) */
#div2 {
background-color: #f0f0f0;
/* 隐藏自身的滚动条,它的滚动将由 JavaScript 控制 */
overflow: hidden;
z-index: 2;
}
/* div3: 左侧标题列 (只纵向滚动) */
#div3 {
background-color: #f0f0f0;
/* 同样隐藏自身的滚动条 */
overflow: hidden;
z-index: 2;
}
/* div4: 主要内容区域 (双向滚动) */
#div4 {
background-color: #ffffff;
/* 开启滚动条,这是驱动所有滚动的核心元素 */
overflow: scroll;
z-index: 1;
}
/* --- 用于创建可滚动内容的内部容器 --- */
/* div2 的内部容器,设置一个很大的宽度来产生横向滚动条 */
#div2 .content-wrapper {
width: 2000px;
height: 100%;
justify-content: space-around; /* 简单排版一下内容 */
font-weight: bold;
}
/* div3 的内部容器,设置一个很大的高度来产生纵向滚动条 */
#div3 .content-wrapper {
width: 100%;
height: 1500px;
flex-direction: column; /* 内容垂直排列 */
justify-content: space-around;
font-weight: bold;
}
/* div4 的内部容器,同时设置很大的宽度和高度 */
#div4 .content-wrapper {
width: 2000px;
height: 1500px;
/* 添加网格背景,方便观察滚动效果 */
background:
linear-gradient(90deg, rgba(0,0,0,0.05) 1px, transparent 1px),
linear-gradient(rgba(0,0,0,0.05) 1px, transparent 1px);
background-size: 100px 50px;
}
</style>
</head>
<body>
<div class="grid-container">
<!-- div1: 左上角固定角 -->
<div id="div1" class="grid-item content-wrapper">
固定角
</div>
<!-- div2: 顶部行,随内容区横向滚动 -->
<div id="div2" class="grid-item">
<div class="content-wrapper">
<span>列标题 1</span><span>列标题 2</span><span>列标题 3</span><span>列标题 4</span><span>列标题 5</span><span>列标题 6</span><span>列标题 7</span><span>列标题 8</span>
</div>
</div>
<!-- div3: 左侧列,随内容区纵向滚动 -->
<div id="div3" class="grid-item">
<div class="content-wrapper">
<span>行标题 A</span><span>行标题 B</span><span>行标题 C</span><span>行标题 D</span><span>行标题 E</span><span>行标题 F</span><span>行标题 G</span><span>行标题 H</span><span>行标题 I</span><span>行标题 J</span>
</div>
</div>
<!-- div4: 主要内容区域,可以双向滚动 -->
<div id="div4" class="grid-item">
<div class="content-wrapper">
<!-- 这里是您的主要数据内容 -->
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取需要同步滚动的三个元素
const div2 = document.getElementById('div2'); // 顶部标题行
const div3 = document.getElementById('div3'); // 左侧标题列
const div4 = document.getElementById('div4'); // 主要内容区
// --- 核心逻辑 ---
// 监听主要内容区 (div4) 的滚动事件
div4.addEventListener('scroll', function() {
// 1. 同步横向滚动
// 将 div4 的水平滚动距离 (scrollLeft) 赋值给顶部标题行 (div2)
// 这样,当内容区向左滚动时,顶部标题行也一起向左滚动
div2.scrollLeft = this.scrollLeft;
// 2. 同步纵向滚动
// 将 div4 的垂直滚动距离 (scrollTop) 赋值给左侧标题列 (div3)
// 这样,当内容区向上滚动时,左侧标题列也一起向上滚动
div3.scrollTop = this.scrollTop;
});
});
</script>
</body>
</html>