PHP $_GET带参跳转时JavaScript记忆滚动位置失效问题
问题原因
你的滚动位置记忆逻辑失效的核心原因是存储和匹配滚动位置时用了完整URL(window.location.href)作为唯一标识:
- 你在无参数的
settings.php页面滚动时,存储的键是不带查询参数的完整地址 - PHP处理完表单跳转到带参数的
settings.php?id=1时,当前页面URL和之前存储的URL字符串不相等,匹配逻辑直接失效,自然读不到之前存的滚动值 - 直接刷新页面时URL完全不变,所以匹配正常,功能生效
修复步骤
- 把所有用于匹配的URL标识从完整
window.location.href换成window.location.pathname,这个属性只会返回页面的路径部分(比如/settings.php),不会携带?后面的查询参数,不管跳转带不带参,只要是同一个页面文件就能匹配到 - 调整滚动恢复的执行时机:DOM ready时页面可能还有图片、异步渲染的内容没加载完成,直接滚动会出现位置偏差,等页面全量load完再执行滚动即可
- 删掉原代码里冗余的数组空值判断逻辑,简化代码,可额外加滚动节流减少localStorage写入频率
修复后完整代码
<script type="text/javascript"> // 页面滚动位置记忆功能 $(document).ready(function () { // 等页面所有资源加载完成后再恢复滚动位置,避免高度计算错误 $(window).on('load', function() { let UrlsObj = localStorage.getItem('rememberScroll'); let ParseUrlsObj = JSON.parse(UrlsObj); // 只取路径部分作为匹配键,忽略查询参数 let windowPath = window.location.pathname; if (!ParseUrlsObj) return false; ParseUrlsObj.forEach(function (el) { if (el.path === windowPath) { $(window).scrollTop(el.scroll); } }); }) }); function RememberScrollPage(scrollPos) { let UrlsObj = localStorage.getItem('rememberScroll'); let urlsArr = JSON.parse(UrlsObj) || []; // 同样用路径作为存储键 let currentPath = window.location.pathname; let matchedIndex = -1; // 查找当前页是否已有存储记录 urlsArr.forEach(function (el, index) { if (el.path === currentPath) { matchedIndex = index; } }); if (matchedIndex >= 0) { // 已有记录就更新滚动值 urlsArr[matchedIndex].scroll = scrollPos; } else { // 无记录就新增 urlsArr.push({ path: currentPath, scroll: scrollPos }); } localStorage.setItem('rememberScroll', JSON.stringify(urlsArr)); } // 监听滚动事件存储位置,加节流避免频繁写入localStorage let scrollTimer = null; $(window).scroll(function () { if (scrollTimer) clearTimeout(scrollTimer); scrollTimer = setTimeout(function() { let topScroll = $(window).scrollTop(); RememberScrollPage(topScroll); }, 100); }); </script>
可选适配说明
如果后续遇到同一路径下不同查询参数对应完全不同页面内容的场景,可以自行拼接需要保留的查询参数到匹配键里,比如只保留type参数、忽略操作类的id/action参数,灵活调整匹配规则即可。
内容的提问来源于stack exchange,提问作者Sour Jack
相关产品推荐
相关产品推荐

