web-dev-qa-db-ja.com

iOSのPhonegapを使用して向きの変更を正しく検出する方法

私はJQTouchの参考資料を探して、以下のこのオリエンテーションテストコードを見つけました。これはモバイルSafariのiOSシミュレータでは正しく機能しますが、PhoneGapでは正しく処理されません。私のプロジェクトは、このテストページを殺しているのと同じ問題に直面しています。 PhonegapのJavaScriptを使って向きの変化を感知する方法はありますか?

window.onorientationchange = function() {
  /*window.orientation returns a value that indicates whether iPhone is in portrait mode, landscape mode with the screen turned to the
    left, or landscape mode with the screen turned to the right. */
  var orientation = window.orientation;
  switch (orientation) {
    case 0:
      /* If in portrait mode, sets the body's class attribute to portrait. Consequently, all style definitions matching the body[class="portrait"] declaration
         in the iPhoneOrientation.css file will be selected and used to style "Handling iPhone or iPod touch Orientation Events". */
      document.body.setAttribute("class", "portrait");

      /* Add a descriptive message on "Handling iPhone or iPod touch Orientation Events"  */
      document.getElementById("currentOrientation").innerHTML = "Now in portrait orientation (Home button on the bottom).";
      break;

    case 90:
      /* If in landscape mode with the screen turned to the left, sets the body's class attribute to landscapeLeft. In this case, all style definitions matching the
         body[class="landscapeLeft"] declaration in the iPhoneOrientation.css file will be selected and used to style "Handling iPhone or iPod touch Orientation Events". */
      document.body.setAttribute("class", "landscape");

      document.getElementById("currentOrientation").innerHTML = "Now in landscape orientation and turned to the left (Home button to the right).";
      break;

    case -90:
      /* If in landscape mode with the screen turned to the right, sets the body's class attribute to landscapeRight. Here, all style definitions matching the
         body[class="landscapeRight"] declaration in the iPhoneOrientation.css file will be selected and used to style "Handling iPhone or iPod touch Orientation Events". */
      document.body.setAttribute("class", "landscape");

      document.getElementById("currentOrientation").innerHTML = "Now in landscape orientation and turned to the right (Home button to the left).";
      break;
  }
}
173
ajpalma

これが私がすることです:

function doOnOrientationChange() {
    switch(window.orientation) {  
      case -90 || 90:
        alert('landscape');
        break; 
      default:
        alert('portrait');
        break; 
    }
}
  
window.addEventListener('orientationchange', doOnOrientationChange);
  
// Initial execution if needed
doOnOrientationChange();

更新2019年5月:window.orientationは廃止予定の機能で、ほとんどのブラウザでサポートされていません MDNによるとorientationchangeイベントは window.orientationに関連付けられている なので、おそらく使用しないでください。

283

私はwindow.onresize = function(){ checkOrientation(); }を使っています。そしてcheckOrientationではwindow.orientationやbody width checkingを使うことができますが、 "window.onresize"は最もクロスブラウザの方法であり、少なくとも私が持っていたモバイルとデスクトップのブラウザの大部分はそうです。でテストする機会があります。

21
Raine

私はiOSとPhonegapについてもかなり新しいですが、私はeventListenerを追加することによってこれを行うことができました。私は(あなたが参照した例を使って)同じことをしました、そしてそれを働かせることができませんでした。しかしこれはトリックをするように見えた:

// Event listener to determine change (horizontal/portrait)
window.addEventListener("orientationchange", updateOrientation); 

function updateOrientation(e) {
switch (e.orientation)
{   
    case 0:
        // Do your thing
        break;

    case -90:
        // Do your thing
        break;

    case 90:
        // Do your thing
        break;

    default:
        break;
    }
}

PhoneGapのGoogleグループを検索する運があるかもしれません 「オリエンテーション」という用語で

オリエンテーションを検出する方法の例として私が読んだ1つの例はPie Guyでした:( gamejs file )。それはあなたが投稿したコードに似ていますが、あなたのようなものです…私はそれをうまく動かすことができませんでした。

1つの警告:eventListenerは私のために働きました、しかしこれが過度に集中的なアプローチであるかどうか私はわかりません。これまでのところこれが私にとって有効な唯一の方法でしたが、もっと効率的で合理的な方法があるかどうかはわかりません。


UPDATE上記のコードを修正しました、今動作します

11
avoision
if (window.matchMedia("(orientation: portrait)").matches) {
   // you're in PORTRAIT mode
}

if (window.matchMedia("(orientation: landscape)").matches) {
  // you're in LANDSCAPE mode
}
10
Alyssa Reyes

orientationchangeイベントを処理している間、ページ内の要素の正しい寸法を取得するにはタイムアウトが必要でしたが、matchMediaは正常に機能しました。私の最後のコード:

var matchMedia = window.msMatchMedia || window.MozMatchMedia || window.WebkitMatchMedia || window.matchMedia;

if (typeof(matchMedia) !== 'undefined') {
  // use matchMedia function to detect orientationchange
  window.matchMedia('(orientation: portrait)').addListener(function() {
    // your code ...
  });
} else {
  // use orientationchange event with timeout (fires to early)
  $(window).on('orientationchange', function() {
    window.setTimeout(function() {
      // your code ...
    }, 300)
  });
}
5
oncode

正しい答えがすでに投稿され、受け入れられていると私は信じていますが、それでも私は自分自身で経験したことがあり、他の人がここで言及した問題があります。

特定のプラットフォームでは、ウィンドウのサイズ(window.innerWidthwindow.innerHeight)やwindow.orientationプロパティなどのさまざまなプロパティは、イベント"orientationchange"が発生した時点では更新されません。多くの場合、プロパティwindow.orientationは、"orientationchange"の起動後数ミリ秒間、undefinedです(少なくとも、iOS上のChromeにはあります)。

私がこの問題に対処するために見つけた最良の方法は次のとおりです。

var handleOrientationChange = (function() {
    var struct = function(){
        struct.parse();
    };
    struct.showPortraitView = function(){
        alert("Portrait Orientation: " + window.orientation);
    };
    struct.showLandscapeView = function(){
        alert("Landscape Orientation: " + window.orientation);
    };
    struct.parse = function(){
        switch(window.orientation){
            case 0:
                    //Portrait Orientation
                    this.showPortraitView();
                break;
            default:
                    //Landscape Orientation
                    if(!parseInt(window.orientation) 
                    || window.orientation === this.lastOrientation)
                        setTimeout(this, 10);
                    else
                    {
                        this.lastOrientation = window.orientation;
                        this.showLandscapeView();
                    }
                break;
        }
    };
    struct.lastOrientation = window.orientation;
    return struct;
})();
window.addEventListener("orientationchange", handleOrientationChange, false);

向きが未定義かどうか、または最後に検出された向きと等しいかどうかを確認しています。どちらかが当てはまる場合は、10ミリ秒待ってから方向をもう一度解析します。向きが適切な値であれば、showXOrientation関数を呼び出します。向きが無効な場合は、チェック機能を繰り返し、有効になるまで毎回10ミリ秒待ちます。

さて、私はいつものようにこれのためにJSFiddleを作るでしょう、しかしJSFiddleは私のために働いていません、そして誰も同じ問題を報告していないのでそれに対する私のサポートバグは閉じられました。他の誰かがこれをJSFiddleにしたい場合は、先に進んでください。

ありがとうございます。これが役に立つことを願っています!

3
WebWanderer

これが私がしたことです:

window.addEventListener('orientationchange', doOnOrientationChange);

function doOnOrientationChange()
{
      if (screen.height > screen.width) {
         console.log('portrait');
      } else {
         console.log('landscape');
      }
}
2
Raul Gomez

このコードは、デバイスが横向きであるかどうかを検出するためのもので、この場合は「サイトを見るために向きを変える」というスプラッシュページを追加します。 iOS、Android、Windows Phoneで動作しています。非常にエレガントで、モバイルサイトに横長のビューを設定しないため、これは非常に便利であると思います。コードはとてもうまくいっています。完全に満足のいくものではない唯一のことは、誰かがランドスケープビューでページをロードした場合、スプラッシュページが表示されないことです。

<script>
(function() {
    'use strict';

    var isMobile = {
        Android: function() {
            return navigator.userAgent.match(/Android/i);
        },
        BlackBerry: function() {
            return navigator.userAgent.match(/BlackBerry/i);
        },
        iOS: function() {
            return navigator.userAgent.match(/iPhone|iPad|iPod/i);
        },
        Opera: function() {
            return navigator.userAgent.match(/Opera Mini/i);
        },
        Windows: function() {
            return navigator.userAgent.match(/IEMobile/i);
        },
        any: function() {
            return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
        }
    };
    if (isMobile.any()) {
        doOnOrientationChange();
        window.addEventListener('resize', doOnOrientationChange, 'false');
    }

    function doOnOrientationChange() {
        var a = document.getElementById('alert');
        var b = document.body;
        var w = b.offsetWidth;
        var h = b.offsetHeight;
        (w / h > 1) ? (a.className = 'show', b.className = 'full-body') : (a.className = 'hide', b.className = '');
    }
})();
</script>

そしてHTML:<div id="alert" class="hide"> <div id="content">This site is not thought to be viewed in landscape mode, please turn your device </div> </div>

1
Luigi
if (window.DeviceOrientationEvent) {
    // Listen for orientation changes
    window.addEventListener("orientationchange", orientationChangeHandler);
    function orientationChangeHandler(evt) {
        // Announce the new orientation number
        // alert(screen.orientation);
        // Find matches
        var mql = window.matchMedia("(orientation: portrait)");

        if (mql.matches)  //true
    }
}
0
M Fauzi Riozi