no message
This commit is contained in:
204
1.html
Normal file
204
1.html
Normal file
@@ -0,0 +1,204 @@
|
||||
<!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;
|
||||
}
|
||||
|
||||
/* 父容器:弹性布局,左右分栏 */
|
||||
.matter {
|
||||
display: flex;
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
gap: 20px; /* 左右间距 */
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
/* 左侧容器:高度较短(示例) */
|
||||
.left {
|
||||
width: 30%;
|
||||
background: #f0f8fb;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
/* 默认静态定位,滚动触底后改为 fixed */
|
||||
position: static;
|
||||
top: auto; /* 初始重置 */
|
||||
bottom: 20px; /* 固定时距离底部的间距 */
|
||||
}
|
||||
|
||||
/* 右侧容器:高度较长(示例) */
|
||||
.right {
|
||||
width: 70%;
|
||||
background: #fef7fb;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
position: static;
|
||||
top: auto;
|
||||
bottom: 20px;
|
||||
}
|
||||
|
||||
/* 触底固定的样式 */
|
||||
.fixed-bottom {
|
||||
position: fixed;
|
||||
/* 固定宽度(与默认布局一致) */
|
||||
width: calc(30% - 10px); /* 30%宽度 - 一半gap(避免布局偏移) */
|
||||
max-height: calc(100vh - 40px); /* 最大高度不超过视口(可选) */
|
||||
overflow: hidden; /* 固定后不再滚动 */
|
||||
}
|
||||
|
||||
/* 右侧固定时的宽度修正(与默认70%一致) */
|
||||
.right.fixed-bottom {
|
||||
width: calc(70% - 10px);
|
||||
}
|
||||
|
||||
/* 页面足够长,确保能滚动 */
|
||||
body {
|
||||
min-height: 200vh;
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
/* 示例内容样式 */
|
||||
.content-item {
|
||||
margin-bottom: 16px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="matter">
|
||||
<div class="left" id="leftContainer">
|
||||
<!-- 左侧内容:较短高度 -->
|
||||
<h3>左侧内容(较短)</h3>
|
||||
<div class="content-item">这是左侧内容的第一行。</div>
|
||||
<div class="content-item">左侧内容相对较短,所以在滚动时会先触底。</div>
|
||||
<div class="content-item">当滚动到一定程度时,左侧会固定在底部。</div>
|
||||
<div class="content-item">此时右侧内容可以继续正常滚动。</div>
|
||||
<div class="content-item">固定后,左侧内容不再随页面滚动。</div>
|
||||
<div class="content-item">这是左侧的最后一行内容。</div>
|
||||
</div>
|
||||
|
||||
<div class="right" id="rightContainer">
|
||||
<!-- 右侧内容:较长高度 -->
|
||||
<h3>右侧内容(较长)</h3>
|
||||
<div class="content-item">这是右侧内容的第一行。</div>
|
||||
<div class="content-item">右侧内容相对较长,可以滚动更多内容。</div>
|
||||
<div class="content-item">右侧内容继续...这是第3行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第4行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第5行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第6行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第7行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第8行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第9行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第10行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第11行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第12行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第13行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第14行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第15行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第16行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第17行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第18行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第19行。</div>
|
||||
<div class="content-item">右侧内容继续...这是第20行。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 获取DOM元素
|
||||
const leftContainer = document.getElementById('leftContainer');
|
||||
const rightContainer = document.getElementById('rightContainer');
|
||||
const matter = document.querySelector('.matter');
|
||||
|
||||
// 记录容器原始样式
|
||||
const originalLeftStyles = {
|
||||
position: leftContainer.style.position,
|
||||
width: leftContainer.style.width,
|
||||
marginLeft: leftContainer.style.marginLeft
|
||||
};
|
||||
|
||||
const originalRightStyles = {
|
||||
position: rightContainer.style.position,
|
||||
width: rightContainer.style.width,
|
||||
marginRight: rightContainer.style.marginRight
|
||||
};
|
||||
|
||||
// 处理滚动事件的核心函数
|
||||
function handleScroll() {
|
||||
// 获取matter容器的位置和尺寸
|
||||
const matterRect = matter.getBoundingClientRect();
|
||||
const matterLeft = matterRect.left;
|
||||
const windowHeight = window.innerHeight;
|
||||
|
||||
// 获取左右容器的位置信息
|
||||
const leftRect = leftContainer.getBoundingClientRect();
|
||||
const rightRect = rightContainer.getBoundingClientRect();
|
||||
|
||||
// 计算左侧容器底部与视口底部的距离
|
||||
const leftBottomToViewportBottom = windowHeight - leftRect.bottom;
|
||||
|
||||
// 计算右侧容器底部与视口底部的距离
|
||||
const rightBottomToViewportBottom = windowHeight - rightRect.bottom;
|
||||
|
||||
// 左侧容器触底检测:当左侧底部即将离开视口(小于0)且容器完全可见时,固定左侧
|
||||
if (leftBottomToViewportBottom < 20 && leftRect.top <= 0 && !leftContainer.classList.contains('fixed-bottom')) {
|
||||
// 固定左侧,保持原位置水平对齐
|
||||
leftContainer.classList.add('fixed-bottom');
|
||||
leftContainer.style.left = `${matterLeft}px`;
|
||||
leftContainer.style.bottom = '20px';
|
||||
} else if (leftRect.top > 0 && leftContainer.classList.contains('fixed-bottom')) {
|
||||
// 当左侧容器顶部重新进入视口时,取消固定
|
||||
leftContainer.classList.remove('fixed-bottom');
|
||||
// 恢复原始样式
|
||||
Object.assign(leftContainer.style, originalLeftStyles);
|
||||
}
|
||||
|
||||
// 右侧容器触底检测:当右侧底部即将离开视口(小于0)且容器完全可见时,固定右侧
|
||||
if (rightBottomToViewportBottom < 20 && rightRect.top <= 0 && !rightContainer.classList.contains('fixed-bottom')) {
|
||||
// 固定右侧,保持原位置水平对齐
|
||||
rightContainer.classList.add('fixed-bottom');
|
||||
rightContainer.style.right = `${window.innerWidth - (matterLeft + matterRect.width)}px`;
|
||||
rightContainer.style.bottom = '20px';
|
||||
} else if (rightRect.top > 0 && rightContainer.classList.contains('fixed-bottom')) {
|
||||
// 当右侧容器顶部重新进入视口时,取消固定
|
||||
rightContainer.classList.remove('fixed-bottom');
|
||||
// 恢复原始样式
|
||||
Object.assign(rightContainer.style, originalRightStyles);
|
||||
}
|
||||
}
|
||||
|
||||
// 窗口大小变化时的处理
|
||||
function handleResize() {
|
||||
// 重置所有固定状态
|
||||
if (leftContainer.classList.contains('fixed-bottom')) {
|
||||
leftContainer.classList.remove('fixed-bottom');
|
||||
Object.assign(leftContainer.style, originalLeftStyles);
|
||||
}
|
||||
|
||||
if (rightContainer.classList.contains('fixed-bottom')) {
|
||||
rightContainer.classList.remove('fixed-bottom');
|
||||
Object.assign(rightContainer.style, originalRightStyles);
|
||||
}
|
||||
|
||||
// 重新触发滚动处理
|
||||
handleScroll();
|
||||
}
|
||||
|
||||
// 初始化
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
// 立即执行一次以初始化
|
||||
handleScroll();
|
||||
// 监听滚动事件
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
// 监听窗口大小变化事件
|
||||
window.addEventListener('resize', handleResize);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user