簡體   English   中英

如何在 iOS 上使用 Phonegap 正確檢測方向變化?

[英]How do I correctly detect orientation change using Phonegap on iOS?

我在下面找到了這個方向測試代碼,以尋找 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;
  }
}

這就是我所做的:

 function doOnOrientationChange() { switch(window.orientation) { case -90: case 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 相關聯,因此可能不應該使用。

我使用window.onresize = function(){ checkOrientation(); } window.onresize = function(){ checkOrientation(); }而在checkOrientation你可以聘請window.orientation或車身寬度檢查,但這個想法是,在“window.onresize”是最跨瀏覽器的方法,至少與廣大的移動和桌面瀏覽器,我已經有機會測試。

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

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

我對 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 Group 中搜索“orientation”這個詞

我讀到的一個關於如何檢測方向的例子是 Pie Guy: ( game , js file )。 它類似於您發布的代碼,但就像您一樣......我無法讓它工作。

一個警告: eventListener 為我工作,但我不確定這是否是一種過於密集的方法。 到目前為止,這是對我有用的唯一方法,但我不知道是否有更好、更簡化的方法。


UPDATE修復了上面的代碼,現在可以使用了

雖然這個問題只涉及 PhoneGap 和 iOS 的使用,雖然已經有人回答了,但我可以對 2019 年用 JS 檢測屏幕方向這個更廣泛的問題補充幾點:

  1. window.orientation屬性已棄用, Android 瀏覽器不支持。有一個較新的屬性可提供有關方向的更多信息 - screen.orientation 但它仍然是實驗性的,不受iOS Safari支持。 因此,為了獲得最佳結果,您可能需要結合使用兩者: const angle = screen.orientation ? screen.orientation.angle : window.orientation const angle = screen.orientation ? screen.orientation.angle : window.orientation

  2. 正如@benallansmith 在他的評論中提到的, window.onorientationchange事件在window.onresize之前被觸發,因此除非在orientationchange 事件之后添加一些延遲,否則您將無法獲得屏幕的實際尺寸。

  3. 有一個Cordova Screen Orientation Plugin用於支持舊的移動瀏覽器,但我相信現在沒有必要使用它。

  4. 還有一個screen.onorientationchange事件,但它已被棄用,不應使用。 添加只是為了答案的完整性。

在我的用例中,我不太關心實際的方向,而是關心窗口的實際寬度和高度,這顯然會隨着方向而變化。 所以我使用resize事件來避免處理orientationchange事件和實現窗口尺寸之間的延遲:

window.addEventListener('resize', () => {
  console.log(`Actual dimensions: ${window.innerWidth}x${window.innerHeight}`);
  console.log(`Actual orientation: ${screen.orientation ? screen.orientation.angle : window.orientation}`);
});

注 1:我在這里使用了 EcmaScript 6 語法,如果需要,請確保將其編譯為 ES5。

注意 2: window.onresize事件也會在虛擬鍵盤切換觸發,而不僅僅是在方向改變時。

在處理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)
  });
}

我相信正確的答案已經發布並被接受,但是我自己也遇到過一個問題,其他一些人也在這里提到過。

在某些平台上,各種屬性,如窗口尺寸( 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);

我正在檢查方向是否未定義或方向是否等於檢測到的最后一個方向。 如果任一為真,我等待十毫秒,然后再次解析方向。 如果方向是正確的值,我會調用showXOrientation函數。 如果方向無效,我繼續循環我的檢查函數,每次等待十毫秒,直到它有效。

現在,我會像往常一樣為此創建一個 JSFiddle,但 JSFiddle 一直沒有為我工作,我的支持錯誤已關閉,因為沒有其他人報告同樣的問題。 如果其他人想把它變成 JSFiddle,請繼續。

謝謝! 我希望這有幫助!

這是我所做的:

window.addEventListener('orientationchange', doOnOrientationChange);

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

我發現這個代碼可以檢測設備是否處於橫向,在這種情況下添加一個啟動頁面,上面寫着“改變方向以查看站點”。 它適用於 iOS、Android 和 Windows 手機。 我認為這非常有用,因為它非常優雅並且避免為移動站點設置橫向視圖。 該代碼運行良好。 唯一不完全令人滿意的是,如果有人在橫向視圖中加載頁面,則不會出現啟動頁面。

<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>

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
    }
}

以下對我有用:

function changeOrientation(){
switch(window.orientation) {
case 0: // portrait, home bottom
case 180: // portrait, home top
 alert("portrait H: "+$(window).height()+" W: "+$(window).width());       
 break;
          case -90: // landscape, home left
          case 90: // landscape, home right
        alert("landscape H: "+$(window).height()+" W: "+$(window).width());
            break;
        }
    }

 window.onorientationchange = function() { 
            //Need at least 800 milliseconds
            setTimeout(changeOrientation, 1000);
        }

我需要超時,因為window.orientation的值不會立即更新

我正在為 iPhone 在 PhoneGap 中創建一個 jQTouch 應用程序。 幾天來我一直在與這個問題作斗爭。 我已經看到幾次建議的 eventlistener 解決方案,但就是無法讓它工作。

最后我想出了一個不同的解決方案。 它基本上使用 settimeout 定期檢查主體的寬度。 如果寬度為 320,則方向為縱向,如果為 480,則為橫向。 然后,如果自上次檢查以來方向發生了變化,它將觸發縱向填充功能或橫向填充功能,您可以在其中為每個方向進行操作。

代碼(注意,我知道代碼中有一些重復,只是還沒有理會它!):

// get original orientation based on body width
deviceWidth = $('body').width();
if (deviceWidth == 320) {
    currentOrientation = "portrait";
}
else if (deviceWidth == 480) {
    currentOrientation = "landscape";
}

// fire a function that checks the orientation every x milliseconds
setInterval(checkOrientation, 500);

// check orientation
function checkOrientation() {
    deviceWidth = $('body').width();
    if (deviceWidth == '320') {
        newOrientation = "portrait";
    }
    else if (deviceWidth == '480') {
        newOrientation = "landscape";
    }
    // if orientation changed since last check, fire either the portrait or landscape function
    if (newOrientation != currentOrientation) {
        if (newOrientation == "portrait") {
            changedToPortrait();
        }
        else if (newOrientation == "landscape") {
            changedToLandscape();
        }
        currentOrientation = newOrientation;
    }
}

// landscape stuff
function changedToLandscape() {
    alert('Orientation has changed to Landscape!');
}

// portrait stuff
function changedToPortrait() {
    alert('Orientation has changed to Portrait!');
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM