増子良太のブログです

増子良太が書いているブログです。テーマをしぼらず、思いついたものをただひたすら書いていきます。

iOSでスクロールでリサイズイベントが実行されてしまう時の対処法

      2016/01/28

こんにちは。

iOSがらみの投稿が続いてしまうのは、コーディング作業が多いためです。

さて、先日こんなJavaScriptを書きました。

$(window).on(‘resize’, function(e){

// リサイズされたら実行する処理を書いてます。

});

windowのサイズがresizeされたら、処理を実行するという、すごく単純なJavaScriptです。ところが、こちらが思っていた結果と違う結果になってしまいました。

なぜかiPhoneでリサイズをしていないのにresizeイベントが実行されているようです。

???

iPhoneってそもそもリサイズとかできないでしたよね??windowのサイズ変更するなんてできたっけ??

その他にも結構色々な処理をしているJavaScriptだったため、別の箇所が原因ではないかと必死に探しましたが見当たらず。。。もしかして、、、とsafariのwebインスペクタに接続してイベントが呼び出されるタイミングを見てみました。

そうすると、なんとスクロールするタイミングでresizeのイベントが実行されているではありませんか!!

大事なことだから、もう一度言います。

スクロールするだけで、resizeイベントが実行されます!!

なんで??と思った皆さん。私も同じでした。

ここからは予想ですが、iPhoneのsafariでWebページを表示し、スクロールすると、上のアドレスバーのところが消えるのがわかるかと思います。

表示領域を大きくするために自動的に隠れてくれる便利な機能です。

ところが、iOSはアドレスバーを消したときに、表示領域が大きくなった = リサイズされた!とresizeイベントを実行します。

たしかにwindowの高さとしてはリサイズされているっちゃーされてる。でもでもでもでも。。。

それはユーザがしたのではなく、iOS自らしたのであって、resizeイベントを実行しなくても良いではないですか!!PC以外でresizeイベントが実行されるなんて夢にも思いませんでしたよ!!

???

ここで新たな疑問が。

Androidも似たような動きをしますよね。アドレスバーが消えるアレ。ではAndroid端末はどのようにイベントが実行されるのか調べてみました。

Androidも機種ごとにバラバラですが、やはりアドレスバーが出ている間はスクロールするとresizeイベントが実行されてしまうようです。

では、どうすればいいか。

  • ユーザーエージェントで判定
    • AndroidやiOSなどが含まないときだけresizeイベントを取得するよう変更する
  • 横幅で判定
    • リサイズされる前の$(window).width()とリサイズ後のwidthを比較し、変更があればresizeイベントを実行する

ってなところですかね。

どちらにしても、resizeイベントはドラッグしている間に複数回実行されるため、あまり重たい処理をresizeイベントで実行しないようにするか、setTimeout関数なんかを使って遅延させるなどの対応が必要です。

 

ちなみに、、、

スマートフォンやタブレットでは画面の向きを縦から横、横から縦に変えたときに起こるイベント、「onorientationchange」イベントがあります。

これもiOSとAndroid(しかも機種によって?)でイベントの実行順序が変わります。

ある端末では

onorientationchange     →    resize

違う端末では

resize    →    onorientationchange

さらに別の端末では

onorientationchange    → スクロールする    →    resize

などなど、実行順序が変わりやすいので気をつけたいところです。

それにしてもスマートフォン対応はややこしい。。。

 - Appple