回答:
Androidのブラウザでの姿勢変化を検出するために、にリスナーを添付するorientationchange
か、resize
上のイベントwindow
:
// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
alert('HOLY ROTATING SCREENS BATMAN:' + window.orientation + " " + screen.width);
}, false);
window.orientation
プロパティを確認して、デバイスの向きを確認してください。Androidスマートフォンの場合、screen.width
またはscreen.height
デバイスの回転に合わせて更新されます。(これはiPhoneには当てはまりません)。
異なるデバイス間での実際の動作は一貫していません。resizeイベントとorientationChangeイベントは、さまざまな頻度で異なるシーケンスで発生する可能性があります。また、一部の値(screen.widthやwindow.orientationなど)は、期待どおりに常に変化するとは限りません。screen.widthは避けてください-iOSで回転しても変わりません。
信頼できるアプローチは、リサイズイベントとorientationChangeイベントの両方をリッスンすることです(安全のためにいくつかのポーリングを行います)。最終的には、向きの有効な値を取得します。私のテストでは、Androidデバイスが180度完全に回転したときにイベントの起動に失敗することがあるので、方向をポーリングするsetIntervalも含めました。
var previousOrientation = window.orientation;
var checkOrientation = function(){
if(window.orientation !== previousOrientation){
previousOrientation = window.orientation;
// orientation changed, do your magic here
}
};
window.addEventListener("resize", checkOrientation, false);
window.addEventListener("orientationchange", checkOrientation, false);
// (optional) Android doesn't always fire orientationChange on 180 degree turns
setInterval(checkOrientation, 2000);
これは私がテストした4つのデバイスからの結果です(ASCIIテーブルでは申し訳ありませんが、結果を表示する最も簡単な方法のように思われました)。iOSデバイス間の一貫性は別として、デバイス間で多くの多様性があります。注:イベントは、発生した順序で一覧表示されます。
| ================================================= ============================= | | デバイス| 発生したイベント| オリエンテーション| innerWidth | screen.width | | ================================================= ============================= | | iPad 2 | サイズ変更| 0 | 1024 | 768 | | (横向き)| オリエンテーションチェンジ| 90 | 1024 | 768 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | iPad 2 | サイズ変更| 90 | 768 | 768 | | (ポートレートへ)| オリエンテーションチェンジ| 0 | 768 | 768 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | iPhone 4 | サイズ変更| 0 | 480 | 320 | | (横向き)| オリエンテーションチェンジ| 90 | 480 | 320 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | iPhone 4 | サイズ変更| 90 | 320 | 320 | | (ポートレートへ)| オリエンテーションチェンジ| 0 | 320 | 320 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | ドロイドフォン| オリエンテーションチェンジ| 90 | 320 | 320 | | (横向き)| サイズ変更| 90 | 569 | 569 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | ドロイドフォン| 方向変更| 0 | 569 | 569 | | (ポートレートへ)| サイズ変更| 0 | 320 | 320 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | Samsung Galaxy | オリエンテーションチェンジ| 0 | 400 | 400 | | タブレット| オリエンテーションチェンジ| 90 | 400 | 400 | | (横向き)| オリエンテーションチェンジ| 90 | 400 | 400 | | | サイズ変更| 90 | 683 | 683 | | | オリエンテーションチェンジ| 90 | 683 | 683 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- | | Samsung Galaxy | オリエンテーションチェンジ| 90 | 683 | 683 | | タブレット| オリエンテーションチェンジ| 0 | 683 | 683 | | (ポートレートへ)| オリエンテーションチェンジ| 0 | 683 | 683 | | | サイズ変更| 0 | 400 | 400 | | | オリエンテーションチェンジ| 0 | 400 | 400 | | ---------------- + ------------------- + ------------ -+ ------------ + -------------- |
previousOrientation
現在の向きで初期化する必要がありますvar previousOrientation = window.orientation;
。180度の回転を無視する場合、つまり、左または右のランドスケープと上下逆または無のバリエーションを区別する必要がない場合は、次を追加します。の最初の行としてcheckOrientation()
:if (0 === (previousOrientation + window.orientation) % 180) return;
ただし、追加のsetTimeout
トリックを行わなくても、180度の高速回転で1 つの orientationchange
イベントしか作成されないiOSでのみ、このメリットが得られます。
two-bit-foolの優れた答えはすべての背景を提供しますが、iOSとAndroid間の向きの変更を処理する方法の簡潔で実用的な要約を試してみましょう:
resize
イベントのみを処理します。window.innerWidth
、window.InnerHeight
ただ行動するだけです。window.orientation
最新ではありません。 resize
のAndroid上のイベント、そして唯一orientationchange
のiOS上のイベントを。window.orientation
(およびwindow.innerWidth
およびwindow.InnerHeight
)に基づいて動作しますこれらのアプローチには、以前の向きを覚えて比較するよりもわずかな利点があります。
window.orientation
は使用できません)。いつでもウィンドウのサイズ変更イベントをリッスンできます。そのイベントで、ウィンドウの幅が高さから高さ(またはその逆)に変わった場合、電話の向きが変更されただけであることがかなりわかります。
HTML5で可能です。
詳しくは、http://slides.html5rocks.com/#slide-orientationをご覧ください(そしてライブデモをお試しください)。
window.addEventListener('deviceorientation', function(event) {
var a = event.alpha;
var b = event.beta;
var g = event.gamma;
}, false);
また、deskopブラウザもサポートしていますが、常に同じ値を返します。
私も同じ問題を抱えていました。Adroidデバイス用にPhonegapとJqueryモバイルを使用しています。適切にサイズ変更するには、タイムアウトを設定する必要がありました。
$(window).bind('orientationchange',function(e) {
fixOrientation();
});
$(window).bind('resize',function(e) {
fixOrientation();
});
function fixOrientation() {
setTimeout(function() {
var windowWidth = window.innerWidth;
$('div[data-role="page"]').width(windowWidth);
$('div[data-role="header"]').width(windowWidth);
$('div[data-role="content"]').width(windowWidth-30);
$('div[data-role="footer"]').width(windowWidth);
},500);
}
これが解決策です:
var isMobile = {
Android: function() {
return /Android/i.test(navigator.userAgent);
},
iOS: function() {
return /iPhone|iPad|iPod/i.test(navigator.userAgent);
}
};
if(isMobile.Android())
{
var previousWidth=$(window).width();
$(window).on({
resize: function(e) {
var YourFunction=(function(){
var screenWidth=$(window).width();
if(previousWidth!=screenWidth)
{
previousWidth=screenWidth;
alert("oreientation changed");
}
})();
}
});
}
else//mainly for ios
{
$(window).on({
orientationchange: function(e) {
alert("orientation changed");
}
});
}
別の落とし穴-一部のAndroidタブレット(私が信じているMotorola Xoomと私がいくつかのテストを行っているローエンドのElonexタブレット、おそらく他のものも)は、ポートレートではなく、ランドスケープモードでwindow.orientation == 0になるように加速度計を設定しています!
すべてのブラウザと互換性のあるソリューションを試すことができます。
以下はorientationchange
互換性の写真です:
したがって、私はorientaionchange
ポリフィルを作成します。これは@media属性に基づいており、orientationchangeユーティリティライブラリを修正します——orientationchange -fix
window.addEventListener('orientationchange', function(){
if(window.neworientation.current === 'portrait|landscape'){
// do something……
} else {
// do something……
}
}, false);
私のEpic 4G Touchでは、javascript android呼び出しが機能する前に、WebChromeClientを使用するようにwebviewを設定する必要があったことに注目する価値があります。
webView.setWebChromeClient(new WebChromeClient());
2ビットフールの答えへの少しの貢献:
ドロイド電話の表に記載されているように、「orientationchange」イベントは「resize」イベントよりも早く発生するため、次のサイズ変更呼び出しがブロックされます(ifステートメントのため)。Widthプロパティはまだ設定されていません。
完全ではないかもしれませんが、回避策は "orientationchange"イベントを発生させないことです。これは、 "if"ステートメントで "orientationchange"イベントバインディングをラップすることでアーカイブできます。
if (!navigator.userAgent.match(/android/i))
{
window.addEventListener("orientationchange", checkOrientation, false);
}
それが役に立てば幸い
(テストはNexus Sで行われました)