Bootstrap移动端全屏Modal下拉刷新实现方法
Bootstrap 5全屏Modal移动端下拉刷新实现方案
要给全屏Modal实现类似普通页面的下拉刷新效果,核心是监听移动端触摸事件并判断下拉动作,以下是具体实现步骤:
1. 调整Modal布局,添加滚动区域和刷新提示
先修改Modal的modal-body,设置滚动样式并添加刷新提示元素:
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"/> <!-- Button trigger modal --> <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal"> Launch demo modal </button> <!-- Modal --> <div class="modal modal-blur fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog modal-fullscreen"> <div class="modal-content"> <div class="modal-header"> <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body" id="modal-scroll-content" style="height: calc(100vh - 136px); overflow-y: auto;"> <!-- 刷新提示区域 --> <div id="refresh-indicator" style="height: 50px; display: none; align-items: center; justify-content: center; color: #6c757d;"> 下拉可以刷新 </div> <!-- 原有内容 --> <p>这里是Modal内容,可滚动...</p> <!-- 可添加更多内容触发滚动条 --> <p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p><p>内容行</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div>
2. 编写触摸事件逻辑,实现下拉刷新
添加JavaScript代码,监听触摸的开始、移动和结束事件,判断下拉动作并触发刷新:
const scrollContent = document.getElementById('modal-scroll-content'); const refreshIndicator = document.getElementById('refresh-indicator'); let startY = 0; let isRefreshing = false; const refreshThreshold = 50; // 触发刷新的最小下拉距离 // 触摸开始:记录起始位置,仅当滚动条在顶部时生效 scrollContent.addEventListener('touchstart', (e) => { if (scrollContent.scrollTop === 0) { startY = e.touches[0].clientY; } }); // 触摸移动:计算下拉距离,显示提示文本 scrollContent.addEventListener('touchmove', (e) => { // 正在刷新或滚动条不在顶部时,不处理 if (isRefreshing || scrollContent.scrollTop !== 0) return; const currentY = e.touches[0].clientY; const diffY = currentY - startY; if (diffY > 0) { // 显示刷新提示,限制最大高度为50px refreshIndicator.style.display = 'flex'; refreshIndicator.style.height = `${Math.min(diffY, 50)}px`; // 根据下拉距离切换提示文本 refreshIndicator.textContent = diffY >= refreshThreshold ? '松开立即刷新' : '下拉可以刷新'; } else { refreshIndicator.style.display = 'none'; } }); // 触摸结束:判断是否触发刷新 scrollContent.addEventListener('touchend', () => { if (isRefreshing) return; const currentHeight = refreshIndicator.offsetHeight; if (currentHeight >= refreshThreshold) { // 进入刷新状态 isRefreshing = true; refreshIndicator.textContent = '正在刷新...'; // 替换为你的实际刷新逻辑(比如请求接口更新内容) setTimeout(() => { // 刷新完成后的操作 refreshIndicator.textContent = '刷新完成'; // 模拟更新内容 scrollContent.insertAdjacentHTML('afterbegin', '<p>新刷新的内容</p>'); // 1秒后重置状态,隐藏提示 setTimeout(() => { refreshIndicator.style.display = 'none'; refreshIndicator.style.height = '50px'; isRefreshing = false; }, 1000); }, 1500); } else { // 未达到阈值,收起提示 refreshIndicator.style.display = 'none'; refreshIndicator.style.height = '50px'; } });
关键细节说明
- 滚动区域设置:通过
height: calc(100vh - 136px)让modal-body占满全屏减去头部和底部高度,overflow-y: auto开启垂直滚动,确保移动端能触摸滚动。 - 状态控制:用
isRefreshing变量防止重复触发刷新,避免多次执行刷新逻辑。 - 阈值判断:设置
refreshThreshold控制触发刷新的最小下拉距离,提升用户体验。 - 提示交互:根据下拉距离切换提示文本,让用户清晰知道当前操作状态。
内容的提问来源于stack exchange,提问作者AJK
相关产品推荐
相关产品推荐

