no message

This commit is contained in:
A1300399510
2025-11-08 22:22:44 +08:00
parent dc871d80c0
commit aa5a7058ad
22 changed files with 1222 additions and 162 deletions

204
1.html Normal file
View 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>