Skip to content

Conversation

Copy link

Copilot AI commented Jan 4, 2026

  • Understand the issue: PJAX scroll position is abnormal when navigating back
  • Analyze the pjax.js code and @sliphua/pjax library
  • Identify root cause: scroll restoration happens BEFORE layout adjustments in pjax:complete
  • Implement fix: Disable built-in scroll restoration and handle it manually after layout changes
  • Address code review feedback:
    • Fix implicit global variable 'selectors'
    • Improve race condition handling with navigation ID tracking
    • Use pathname + search as storage key to handle URL fragments correctly
    • Fix scroll behavior: scroll to top on forward nav, restore position on back/forward
  • Build the project successfully
  • Run security check (codeql_checker) - No alerts found

Summary

This fix addresses the issue where page scroll position was abnormal when navigating back with PJAX enabled.

Behavior

  • Forward navigation (clicking links): Scrolls to top of page (unless URL has hash)
  • Back/forward navigation (popstate): Restores to previously saved scroll position
  • Each page maintains its own independent scroll position
Original prompt

This section details on the original issue you should resolve

<issue_title>在启用PJAX的情况下,后退时页面滚动位置异常</issue_title>
<issue_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 位)

截图
打开文章前:
Image

打开文章后:

Image

执行后退操作后:

Image

补充信息:
可以注意到,首页向下滚动了.
</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits January 4, 2026 11:14
The issue was that the pjax library's built-in scroll restoration
happened BEFORE the layout adjustments in pjax:complete handler,
causing the visual scroll position to shift after layout changes.

This fix:
1. Disables built-in scroll restoration (scrollRestoration: false)
2. Disables auto scroll to top (scrollTo: false)
3. Manually saves scroll position before navigation (pjax:send)
4. Restores scroll position AFTER all layout adjustments (pjax:complete)
5. Only restores scroll on back/forward navigation (popstate)
6. Removes redundant popstate event listener

Co-authored-by: Shiroiame-Kusu <42903464+Shiroiame-Kusu@users.noreply.github.com>
…ndition handling

1. Added 'let' declaration for 'selectors' variable to fix implicit global
2. Replaced boolean flag with navigation ID tracking system:
   - navigationId: increments on each pjax:send
   - popstateExpectedId: set to navigationId + 1 on popstate
   - Only restores scroll when IDs match, preventing race conditions

Co-authored-by: Shiroiame-Kusu <42903464+Shiroiame-Kusu@users.noreply.github.com>
Co-authored-by: Shiroiame-Kusu <42903464+Shiroiame-Kusu@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix page scroll position issue when using PJAX on back navigation Fix PJAX scroll position restoration on back/forward navigation Jan 4, 2026
Copilot AI requested a review from Shiroiame-Kusu January 4, 2026 11:23
@Shiroiame-Kusu
Copy link
Member

@copilot you delete line 134-140: window.addEventListener('popstate', (e) => {
auto_height();
hitokoto()
PE();
CE();
post_list_show_animation();
}, false); I just wonder will this cause any problems?dig deeper and find out, if so, then do fix

Copy link
Author

Copilot AI commented Jan 4, 2026

@copilot you delete line 134-140: window.addEventListener('popstate', (e) => {
auto_height();
hitokoto()...

Investigated the pjax library's popstate handling. When back/forward navigation occurs:

  1. popstate fires → pjax's internal handler calls this.load()
  2. this.load() triggers the full pjax cycle including pjax:complete

The removed listener was calling auto_height(), hitokoto(), PE(), CE(), post_list_show_animation() — all of which are already called in the pjax:complete handler (lines 104-106, 135, 149). The removal eliminates redundant duplicate calls without affecting functionality.

@Shiroiame-Kusu
Copy link
Member

@copilot Currently, all pages share the same Y-axis position/scroll progress, which is obviously not what we want. What we need is that when entering a page or navigating back to a previous page, it should resume from the last viewed position. If the page has not been scrolled before, it should start from the top, rather than all pages sharing a single scroll progress.

…rward

- Forward navigation (clicking links): now scrolls to top
- Back/forward navigation (popstate): restores saved scroll position
- Each page maintains its own scroll position via sessionStorage
- URLs with hash fragments preserve scroll behavior

Co-authored-by: Shiroiame-Kusu <42903464+Shiroiame-Kusu@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jan 4, 2026

@copilot Currently, all pages share the same Y-axis position/scroll progress, which is obviously not what we want. What we need is that when entering a page or navigating back to a previous page, it s...

Fixed in fc44048. The issue was that scrollTo: false prevented scrolling to top on forward navigation.

Now:

  • Forward nav (clicking links): scrolls to top
  • Back/forward nav (popstate): restores saved position per-page (keyed by pathname + search)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

在启用PJAX的情况下,后退时页面滚动位置异常

2 participants