画面遷移しても地図の位置座標を維持。sessionStorageを使って制御してみた。


Leafletを使って地図を使ったアプリを作成しいていましたが、画面遷移(あるいはリロード)したときに必ずデフォルトの座標に戻ってしまい、使いづらさを感じていました。
そこで、画面遷移しても遷移前に見ていた地図座標を保持したいと思いsessionStorageを使いました。

具体的に実現した方法をまとめてみます。

開発環境

Ruby 2.6.5
Ruby on Rails 5.2.6
Leaflet.js 1.7.1

Leafletの初期設定

ここではLeaflet.jsの導入は省略します。
Leaflet.js
まずLeafletで地図を表示するためのデフォルトの設定をします。
マップタイルはオープンソースのOpenStreetMapを使用します。

index.html
<div id="mapid"></div>

<script>
 //デフォルトの位置座標とzoomを指定
 var mymap = L.map('mapid').setView([35.680196, 139.766746], 16);

//マップタイルを指定
 L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: 'c <a href="//osm.org/copyright">OpenStreetMap</a> contributors, <a href="//creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
    maxZoom: 18,
    minZoom: 3,
}).addTo(mymap);
</script>

デフォルト座標35.680196, 139.766746は東京駅を中心にした地図を表示しています。

しかし、この設定だと地図をスクロールして別の地域を表示していても、画面を遷移(またはリロード)する度にまた東京駅に戻ってしまいますよね。アプリによってはこの挙動が不便になる場合もあります。

sessionStorageとは?

そこでsessionStorageという仕組みを使いました。

sessionStorageとは、JavaScriptを用いてブラウザにデータを保存できる仕組みです。HTML5から導入されたWebStorageの1つです。
ブラウザ画面を開いているセッションにおいてだけデータを保持でき、新しいタブやウィンドウを開くと新しいセッションが開始します。
画面遷移やリロードしてもデータが保持されるのが特徴です。

sessionStorage

他にlocalStorageがありますが、こちらはブラウザを閉じてもデータ保持が持続してしまうので、sessionStorageほど気軽には使えないですね。

sessionStorageで画面遷移前の位置情報を保持する

地図の位置情報をsessionStorageに保持してみます。

まず、現在表示している地図の中心の位置座標をJavaScriptで取得します。
以下のコードを追加します。

index.html
<script>
//下記を追記
mymap.on('move', function(e){
    currentPosi = mymap.getCenter();
  currentZoom = mymap.getZoom();
}
</script>

地図の中心座標とzoomの値を変数に格納します。これで地図を動かすたびに、位置座標を取得して変数に保持することができます。

次に取得した位置座標のデータをsessionStorageに保持していきましょう。

sessionStorageに保持するには、キーと値を設定します。
sessionStorage.setItem('key', value)

index.html
<script>
mymap.on('move', function(e){
    currentPosi = mymap.getCenter();
  currentZoom = mymap.getZoom();
  //下記を追記
  sessionStorage.setItem('currentLat',currentPosi.lat);
  sessionStorage.setItem('currentLng',currentPosi.lng);
  sessionStorage.setItem('currentZoom',currentZoom);
}
</script>

GoogleChromeの検証画面でsessionStorageの値が保持されているかどうかを確認できます。

Application > Storage > sessionStorage > http:~

設定したキーと値がセットになって保持されていることが確認できました。
これで画面遷移してもデータを持ち越すことができます。

sessionStorageの値を受け取り、リロード後の地図に反映

次に画面遷移した時にこの位置座標を受け取り、地図に反映させます。

index.html

<script>
  var sessionKey = sessionStorage.getItem('currentLat');

 //sessionStorageが空だった場合と値が存在する場合で分岐し、デフォルト値を動的に生成
 if( sessionKey == null ){
    var defaultLatlng = [35.678362, 139.715387];
    var defaultZoom = 13;
  } else {
    var defaultLatlng = [Number(sessionStorage.currentLat), Number(sessionStorage.currentLng)];
    var defaultZoom = Number(sessionStorage.currentZoom);
    };
  var mymap = L.map('mapid').setView(defaultLatlng, defaultZoom);//直書きだった座標とzoomの値を、変数にする

//以下省略

</script>

これで画面遷移前の位置情報を、画面遷移後(今回はリロード後)の地図に反映することができました。