iPhone と Android の onOrientationChange タイミングの違い
Androidのブラウザにて。Android 2.2から、iPhoneと同じように縦持ち・横持ちが変わった際に発生するイベント「window.onorientationchange」が使えるようになっているようです。ですが、このイベントが起きるタイミングがiPhoneとAndroidで異なっているようです。
var $win = $(window); var debug = $('#debug'); $win.bind( 'orientationchange', function() { debug.html( debug.html() + 'orient:' + $win.width() + ', ' ); } ) .bind( 'resize', function(){ debug.html( debug.html() + 'resize:' + $win.width() + ', ' ); } );
上のJavaScriptを実行すると、iPhoneの場合は、
- ウィンドウのサイズ変更 → resizeイベント → orientationchangeイベント
という順番でイベントが発生していることがわかります(なんだか、resizeイベントが2回発生するケースもあるみたい)。
ところが Android 2.2の場合は、
- orientationchangeイベント → ウィンドウのサイズ変更 → resizeイベント
という順番になります。
ちなみに、Android 2.1以前は、typeof window.onorientationchange === 'undefined' なので、
- ウィンドウサイズの変更 → resizeイベント
となっています。
orientationchangeイベントだけだと、iPhoneの場合は変更後の、Androidの場合は変更前の値を持ってきてしまうことになりますので、ウィンドウサイズを元に表示を変更しようとした場合にはおかしなことになってしまいます。以下のように判定をしている場合には、注意が必要ですね。
if ( typeof window.onorientationchange === 'object' ) { $(window).bind( 'orientationchange', function(){ hoge(); } ); } else { $(window).bind( 'resize', function(){ hoge(); } ); }
Androidの場合には、resizeイベントを使うようにすると、iPhoneと共通化ができると思います。
var isAndroid = navigator.userAgent.indexOf('Android') != -1; if ( typeof window.onorientationchange === 'object' && ! isAndroid ) { $(window).bind( 'orientationchange', function(){ hoge(); } ); } else { $(window).bind( 'resize', function(){ hoge(); } ); }
ちなみにAndroidのresizeイベントは、アドレスバーが表示されている間はスクロールするだけで発生するようなので、重い処理はさせないほうが良さそうです。