如何阻止iOS端Safari在输入框焦点切换时自动滚动
解决方案
1. 禁用聚焦触发的自动滚动
给模态框内的所有可聚焦元素(输入框、按钮等)添加焦点处理,利用浏览器原生的preventScroll选项阻止滚动:
// 获取模态框内所有可聚焦元素 const focusableElements = document.querySelectorAll('.modal input, .modal button, .modal [tabindex]:not([tabindex="-1"])'); focusableElements.forEach(el => { el.addEventListener('focus', (e) => { e.preventDefault(); el.focus({ preventScroll: true }); }, { capture: true }); });
2. 模态框打开时锁定页面滚动
避免页面滚动导致模态框移位,给body添加锁定样式:
body.modal-locked { overflow: hidden; position: fixed; width: 100%; }
配合JavaScript记录并恢复滚动位置:
let savedScrollPos = 0; // 打开模态框时调用 function lockPageScroll() { savedScrollPos = window.scrollY; document.body.classList.add('modal-locked'); document.body.style.top = `-${savedScrollPos}px`; } // 关闭模态框时调用 function unlockPageScroll() { document.body.classList.remove('modal-locked'); window.scrollTo(0, savedScrollPos); document.body.style.top = ''; }
3. 确保模态框定位正确
模态框必须使用固定定位,保证它始终相对于视口:
.modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; } .modal-content { position: relative; background: #fff; padding: 2rem; border-radius: 8px; max-width: 90%; max-height: 90vh; overflow-y: auto; }
4. 可选:保留无障碍焦点陷阱
既禁用滚动,又保证用户在模态框内循环切换焦点(符合无障碍规范):
const modal = document.querySelector('.modal-overlay'); const firstFocusEl = focusableElements[0]; const lastFocusEl = focusableElements[focusableElements.length - 1]; modal.addEventListener('keydown', (e) => { if (e.key === 'Tab') { if (e.shiftKey && document.activeElement === firstFocusEl) { e.preventDefault(); lastFocusEl.focus({ preventScroll: true }); } else if (!e.shiftKey && document.activeElement === lastFocusEl) { e.preventDefault(); firstFocusEl.focus({ preventScroll: true }); } } else if (e.key === 'Escape') { // 替换为你的模态框关闭逻辑 modal.style.display = 'none'; unlockPageScroll(); } });
内容的提问来源于stack exchange,提问作者Iftach
相关产品推荐
相关产品推荐

