我正在开发一个网页,根据我执行相应动画的下一个或后退动作,问题出现在使用 pushstate 时。当我收到事件时,我如何知道用户是否使用 Pushstate API 单击了后退或前进历史按钮?还是我必须自己实现一些东西?
如果 popstate 事件来自 HTML5 pushstate 的后退或前进操作,我如何检索?
IT技术
javascript
html
browser-history
pushstate
                    2021-03-12 04:17:26
                
                    
                
            
        2个回答
            你必须自己实现它,这很容易。
- 调用时
pushState给数据对象一个唯一的递增 id (uid)。 - 当
onpopstate处理程序被调用时;根据包含最后一个状态 uid 的持久变量检查状态 uid。 - 使用当前状态 uid 更新持久变量。
 - 根据状态 uid 是大于还是小于上一个状态 uid 执行不同的操作。
 
此答案应适用于单页推送状态应用程序、多页应用程序或两者的组合。
(更正以修复History.lengthMesqualito 评论中解决的错误。)
怎么运行的
我们可以轻松地侦听历史堆栈的新条目。我们知道,对于每个新条目,规范要求浏览器:
- “在当前条目之后删除浏览上下文会话历史记录中的所有条目”
 - “在最后添加一个新条目”
 
因此,在进入时:
新入场位置 = 最后显示的位置 + 1
那么解决办法是:
- 用它在堆栈中的位置标记每个历史条目
 - 在会话存储中跟踪最后显示的位置
 - 通过比较两者来发现行进方向
 
示例代码
function reorient() // After travelling in the history stack
{
    const positionLastShown = Number( // If none, then zero
      sessionStorage.getItem( 'positionLastShown' ));
    let position = history.state; // Absolute position in stack
    if( position === null ) // Meaning a new entry on the stack
    {
        position = positionLastShown + 1; // Top of stack
        // (1) Stamp the entry with its own position in the stack
        history.replaceState( position, /*no title*/'' );
    }
    // (2) Keep track of the last position shown
    sessionStorage.setItem( 'positionLastShown', String(position) );
    // (3) Discover the direction of travel by comparing the two
    const direction = Math.sign( position - positionLastShown );
    console.log( 'Travel direction is ' + direction );
      // One of backward (-1), reload (0) and forward (1)
}
addEventListener( 'pageshow', reorient );
addEventListener( 'popstate', reorient ); // Travel in same page
另请参阅代码的实时副本。
局限性
此解决方案忽略外部页面的历史记录条目,对于应用程序来说是陌生的,就好像用户从未访问过它们一样。它仅计算与最后显示的应用程序页面相关的行进方向,而不管其间访问过的任何外部页面。如果您希望用户将外部条目推送到堆栈上(请参阅 Atomosk 的评论),那么您可能需要一种解决方法。
其它你可能感兴趣的问题