Pjax defunkt版で切り替えエフェクトの実装 戻る/進むも対応

2017/09/20

web制作

Pjax構築したいサイトでIE11に対応する場合、defunkt版のPjaxを使うことになると思います。
ページ切り替えを、エフェクトイン → HTMLを書き換え → エフェクトアウトの流れで実装すると
ブラウザの 戻る/進む でHTMLが瞬時に変更されてしまい困ります。
この現象は jquery.pjax.js を少し調整すると解消できるので、やり方を紹介します。

Pjax defunkt

※ jquery v3.2.1、pjax v2.0.1で確認しています。

目次

  1. 普通にPjaxでページ切り替えエフェクトを実装してみる。
  2. jquery.pjax.jsを調整して戻る/進むの書き換えを遅らせる
  3. エフェクトが終わる前に戻る/進むを行うと表示が崩れる場合の対処

普通にPjaxでページ切り替えエフェクトを実装してみる。

まずは jquery.pjax.js を触らず普通にフェードで切り替える実装をしてみます。

index.html

page2.html

script.js

サンプル

大体こんな感じの実装になりました。
アンカークリック or 戻る/進むで書き換えるHTMLをフェードアウト
見えなくなった状態にしてからHTMLをPjaxで書き換えてフェードイン
アンカーの動作は問題ありませんが、戻る/進むでHTMLが瞬時に変更されます。


jquery.pjax.jsを調整して戻る/進むの書き換えを遅らせる

jquery.pjax.js の462行目 popstateEvent の第2引数に1行追加、486行目をコメントアウトします。
それに合わせて script.js も微調整します。

jquery.pjax.js

script.js

サンプル

戻る/進む でHTMLが瞬時に変更される理由ですが
script.js のフェードアウトよりも前に
jquery.pjax.js の486行目 container.html(contents) で表示されているHTMLが contents(遷移先のHTMLデータ) に書き換えられているからです。

selector.html(val) はjqueryのAPIで、selectorの中身をvalで書き換える処理です。

この処理を jquery.pjax.js で行わずに script.js で行います。
contents を script.js で扱う為 popstateEvent の引数に contents を追加しました。

script.js の pjaxPopstate に追加した e.contents に jquery.pjax.js の contents が格納されているので
フェードアウトしてから $(‘#wrap’).html(e.contents); で書き換えます。
これで意図した動きになります。


エフェクトが終わる前に戻る/進むを行うと表示が崩れる場合の対処

ここまでの調整だけで一応形にはなっていますが、エフェクトが終わる前に戻る/進むを素早く行うと
URLやtitleは変わっているのにHTMLが変わっていない現象が発生します。
素早く戻る/進むを行う例
対処方法はたくさんあると思いますが、今回は自分なりに一番楽だと思う対処法でサクッとやります。

この現象が発生する理由は、contents の中身がHTMLを書き換える前のデータに上書きされているからです。
jquery.pjax.js が遷移先のHTMLデータを保管する処理で、エフェクトが終わる前(HTMLを書き換える前)のデータを上書き保管している為

通常はHTMLを瞬時に変更しているので、この現象が発生しません。

なので、通常と同じように瞬時に変更するHTMLをダミーで用意します。

index.html

page2.html

jquery.pjax.js

script.js

サンプル

各HTMLに #pjax_cache を追加しています(idは適当)

jquery.pjax.js の調整は、書き換えと保管の対象になるHTMLを #pjax_cache に変更しています。
更に前の段階でコメントアウトした container.html(contents) を復活させています。
この処理は #pjax_cache を書き換える処理になっているので問題ありません。

script.js は、pjaxの処理が完了したタイミングで #wrap の書き換えを #pjax_cache にも反映させるよう調整しました。

これで contents のHTMLが #pjax_cache のHTMLで上書きされ、
戻る/進む を連打しても正となるHTMLが表示されます。

※ #pjax_cache を display:none 等で非表示にしておく


SNSでシェアする

コメントを残す