-
-
Notifications
You must be signed in to change notification settings - Fork 409
Open
Labels
bugSomething isn't workingSomething isn't working
Description
问题描述:
在启用PJAX的情况下,后退时页面滚动位置异常。
问题出处:
iro主题设置--全局设置--额外设置--功能--PJAX局部刷新
实际行为描述:
启用"PJAX 局部刷新"后,在博客首页打开任意文章,然后点击浏览器的后退按钮(鼠标后退按钮)回到首页,首页的页面位置与打开文章前对比,首页自动向下滚动了.
预期的行为:
启用"PJAX 局部刷新"后,在博客首页打开任意文章,然后点击浏览器的后退按钮,返回上级页面时,上级页面应保持原来的滚动位置
复现步骤:
打开pjax后稳定触发
配置与环境:
- 问题站点链接:
- https://kiseki.blog/
- https://www.suiyue.site/
- PHP 版本:8.3.24
- 数据库类型 / 版本:mysqlnd 8.3.24
- WordPress 版本:6.8.3
- 主题版本:3.0.4
- 使用的插件:
- WP Statistics
- WordPress 导入工具
- 浏览器:Google Chrome 版本 142.0.7444.163(正式版本) (64 位)
打开文章后:
执行后退操作后:
补充信息:
可以注意到,首页向下滚动了.
解决方案(借助AI)
在主题的functions.php文件末尾,iro_action_operator();调用之前添加以下代码:
代码说明:
该解决方案通过监听PJAX事件,在页面跳转前保存当前滚动位置,在返回时恢复位置,确保用户体验的一致性。
add_action('wp_footer', function() {
?>
<script>
(function() {
console.log('=== 改进的PJAX滚动修复 ===');
var savedScrollPositions = {};
var lastValidScrollY = 0;
var isProcessing = false;
// 记录最后一次有效滚动位置
var scrollTimer = null;
window.addEventListener('scroll', function() {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function() {
if (window.scrollY > 10) { // 只记录有意义的滚动位置
lastValidScrollY = window.scrollY;
console.log('记录有效滚动位置:', lastValidScrollY);
}
}, 100);
});
// 改进的PJAX事件处理
document.addEventListener('pjax:send', function() {
if (isProcessing) return;
isProcessing = true;
// 使用最后一次有效滚动位置,而不是当前可能已被重置的位置
var currentUrl = window.location.href;
var scrollToSave = lastValidScrollY > 0 ? lastValidScrollY : window.scrollY;
savedScrollPositions[currentUrl] = {
x: window.scrollX,
y: scrollToSave,
time: Date.now(),
valid: scrollToSave > 10 // 标记是否有效
};
console.log('PJAX发送 - 保存位置:', scrollToSave, '有效:', scrollToSave > 10);
setTimeout(function() {
isProcessing = false;
}, 50);
});
// 处理完成事件
document.addEventListener('pjax:complete', function() {
setTimeout(function() {
var currentUrl = window.location.href;
var savedPos = savedScrollPositions[currentUrl];
if (savedPos && savedPos.valid && savedPos.y > 10) {
console.log('PJAX完成 - 尝试恢复位置:', savedPos.y);
// 分步滚动,确保生效
var attempts = 0;
var scrollInterval = setInterval(function() {
attempts++;
window.scrollTo(savedPos.x, savedPos.y);
if (Math.abs(window.scrollY - savedPos.y) < 10 || attempts >= 5) {
clearInterval(scrollInterval);
console.log('滚动完成 - 最终位置:', window.scrollY, '目标位置:', savedPos.y);
}
}, 50);
}
}, 100);
});
// 改进的popstate处理
window.addEventListener('popstate', function(event) {
setTimeout(function() {
var currentUrl = window.location.href;
var savedPos = savedScrollPositions[currentUrl];
if (savedPos && savedPos.valid && savedPos.y > 10) {
console.log('POPSTATE - 恢复位置:', savedPos.y);
var attempts = 0;
var scrollInterval = setInterval(function() {
attempts++;
window.scrollTo(savedPos.x, savedPos.y);
if (Math.abs(window.scrollY - savedPos.y) < 10 || attempts >= 5) {
clearInterval(scrollInterval);
console.log('Popstate滚动完成');
}
}, 50);
}
}, 150);
});
// 确保浏览器使用自动滚动恢复
if (window.history && window.history.scrollRestoration) {
window.history.scrollRestoration = 'auto';
console.log('设置历史记录滚动恢复: auto');
}
console.log('=== 改进方案加载完成 ===');
})();
</script>
<?php
});
iro_action_operator();```
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
