◆ デフォルトの仕様が変わって Ctrl 押さないとマウスでズーム操作できない
◆ gestureHandling プロパティで元の動作に戻すことは可能
◆ もっと便利にフォーカス中のみ Ctrl 不要になるようにした

最近 ブログやオフィシャルサイトの GoogleMaps の埋め込みでこういう表示をよく見ます

gmap-greedy

夏くらいから でしょうか?


端から端まで地図があるページだと 地図のところでスクロールできなくなるのでありがたいのですが  地図がサイドバーの中など小さくある場合には毎回 Ctrl キーを押すのがとても面倒です

完全に地図検索用のページで ヘッダやフッタはあるものの地図を見るのがメインになってるページですらこの警告が出てきます


ここまで来ると便利だから流行ってる方法とかいうレベルじゃなく仕様変更でデフォルトでこうなってるように思えます

Change log を見てみると
https://developers.google.com/maps/documentation/javascript/releases?hl=ja

2017/8/16 に更新された 3.30 で gestureHandling プロパティが導入されたようです
これは 2016/11/15 の 3.27 で experimental version として利用可能になったプロパティです

gestureHandling

gestureHandling プロパティには 4 種類の値がセットできます

  • greedy
  • cooperative
  • none
  • auto

greedy はこれまでと一緒で 地図内でマウスホイール回したり タップ操作でスワイプすれば地図がズームしたりパンされたりします

cooperative はこういったページ操作を邪魔しないためのもので ズームするには Ctrl キーを押さないとだめで タップでパンするには二本指じゃないとだめになります

none だとマウスやタップでのズームやパンが全くできなくなります

auto にすれば スクロールバーがあったり iframe の中なら cooperative それ以外なら greedy という風に自動でページの邪魔にならないようになります


これまでのに戻したいならオプションに {gestureHandling: "greedy"} を指定すれば良いです


初期化するところでこんな感じです
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 10,
center: {lat: 35.36105612, lng: 138.72711182},
streetViewControl: true,
gestureHandling: "greedy",
})

cooperative をもっと便利にしたい

cooperative にするとページのスクロールを邪魔しないのですが ずっと Ctrl 押さなくても一度地図にフォーカス当てたらフォーカスはずすまでは地図操作をしてほしいですよね

なのでこんなのを作りました

let active_google_maps = null
const elem2map = new WeakMap()

function initMap(elem, option){
const map = new google.maps.Map(elem, option)
elem2map.add(elem, map)
elem.classList.add("google-maps-host")
return map
}

function getMapsFromElement(elem){
return elem2map.get(elem)
}

window.addEventListener("mousedown", eve => {
const map_host = eve.target.closest(".google-maps-host")
if(map_host){
active_google_maps = getMapsFromElement(map_host)

// enable scroll zooming on got focus
active_google_maps.setOptions({gestureHandling: "greedy"})
}else{
if(active_google_maps){
// disable scroll zooming on lost focus
active_google_maps.setOptions({gestureHandling: "auto"})
}
}
}, true)

地図作成は initMap 関数を使います
ターゲットにする要素とオプションを渡します

やってることは 地図内をクリックしたときに gestureHandling を greedy に切り替え 地図外をクリックしたときに cooperative (auto) に切り替えています

リスナが click じゃなくて mousedown になっていますが これはいきなりドラッグした場合で地図の外でマウスを離すとパンしたのに地図内でクリックした扱いにならないからです


できれば Chrome Extension 化して全部のページの GoogleMaps で動くようにしたかったのですが どの要素が地図をホストしてるかのチェックと DOM 要素から GoogleMaps オブジェクトを取得するのが無理そうなので結局自身で作るサイトでしか使えない方法になりました

GoogleMaps のデフォルトがこういう動きするようになればいいのですけどね