私は、対応するアニメーションを実行する次のアクションまたは戻るアクションに応じて、pushstateを使用するときに問題が発生するWebページを開発しています。イベントを受け取ったときに、ユーザーがPushstate APIを使用して履歴ボタンを前後にクリックしたかどうかを知る方法、または自分で何かを実装する必要がありますか?
自分で実装する必要がありますが、これは非常に簡単です。
pushState
を呼び出すと、データオブジェクトに一意の増分ID(uid)が与えられます。onpopstate
ハンドラーが呼び出されたとき。最後の状態uidを含む永続変数に対して状態uidを確認します。この回答は、単一ページのプッシュ状態のアプリ、複数ページのアプリ、またはその2つの組み合わせで機能するはずです。 (Mesqualitoのコメントで対処されたHistory.length
バグを修正するために修正されました。)
履歴スタックへの新しいエントリを簡単に聞くことができます。新しいエントリごとに、 specification にはブラウザが以下を要求することがわかっています。
したがって、エントリの瞬間に:
新しいエントリの位置=最後に表示された位置+ 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) or forward (1)
}
addEventListener( 'pageshow', reorient );
addEventListener( 'popstate', reorient ); // Travel in same page
コードの live copy も参照してください。
このソリューションは、ユーザーが一度もアクセスしたことがないかのように、アプリケーションにとって外部の外部ページの履歴エントリを無視します。途中でアクセスした外部ページに関係なく、最後に表示されたアプリケーションページに対してのみ移動方向を計算します。ユーザーが外部エントリをスタックにプッシュすることを期待している場合(Atomoskのコメントを参照)、回避策が必要になる場合があります。