मैं iOS पर Phonegap का उपयोग करके अभिविन्यास परिवर्तन का सही पता कैसे लगा सकता हूं?


178

मुझे JQTouch संदर्भ सामग्री की तलाश में नीचे यह अभिविन्यास परीक्षण कोड मिला। यह मोबाइल सफ़ारी पर 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;
  }
}

जवाबों:


297

मैं यह करता हूं:

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: window.orientation एक पदावनत सुविधा है और एमडीएन के अनुसार अधिकांश ब्राउज़रों द्वारा समर्थित नहीं है । orientationchangeघटना है window.orientation के साथ जुड़े हैं और इसलिए शायद नहीं किया जाना चाहिए।


3
यह एकमात्र समाधान है जो इस चर्चा से मेरे लिए काम करता है :) +1
एतादज 15'12

9
मैंने कियाwindow.onorientationchange = function() { setTimeout(functionName, 0); };
कर्क स्ट्रोबेक

11
ब्याज से बाहर, आपने सेटटाइमआउट कर्क का उपयोग क्यों किया?
बैकडेस्क

10
सावधान रहे! यह उपकरण विशिष्ट है - डिग्री उपकरणों के मानक अभिविन्यास से अंतर को संदर्भित करता है। दूसरे शब्दों में, यदि टैबलेट को परिदृश्य में उपयोग करने के लिए डिज़ाइन किया गया है, तो इसका मतलब होगा कि यह पोर्ट्रेट मोड में है। इस के आसपास एक काम के रूप में, मैं शुरू में अभिविन्यास को स्टोर करने के लिए विंडो की ऊंचाई बनाम चौड़ाई की जांच करता हूं, और यदि कोई बदलाव है तो इसे अपडेट करने के लिए ओरिएंटचेंज का उपयोग करें।
बेलेन्स्मिथ

15
इसके अतिरिक्त, मैंने पाया है कि अभिविन्यास-परिवर्तन से पहले चौड़ाई और ऊंचाई बदल जाती है, इसलिए चौड़ाई और ऊंचाई का सही ढंग से उपयोग करने के लिए अभिविन्यास का पता लगाने के लिए थोड़ी देरी की आवश्यकता होती है। इसके लिए, मैं वर्तमान अभिविन्यास को संग्रहीत करता हूं, और जब एक परिवर्तन का पता लगाया जाता है, तो मैं 50ms की वृद्धि में अभिविन्यास में 250ms तक के बदलाव की जांच करता हूं। एक बार जब एक अंतर पाया जाता है, तो मैं उसके अनुसार पेज को अपडेट करता हूं। मेरे नेक्सस 5 में, यह आमतौर पर 150ms के बाद चौड़ाई बनाम ऊंचाई अंतर का पता लगाता है।
बेलांस्मिथ

24

मैं का उपयोग करता हूं window.onresize = function(){ checkOrientation(); } और checkOrientation में आप window.orientation या body width check कर सकते हैं लेकिन विचार यह है कि, "window.onresize" सबसे क्रॉस ब्राउजर विधि है, कम से कम मोबाइल और डेस्कटॉप ब्राउजर्स के साथ जो मेरे पास है के साथ परीक्षण करने का अवसर।


1
यह एक बड़ा मुद्दा है। यदि आप एक वेब-फेसिंग तकनीक का उपयोग कर विकसित कर रहे हैं, तो यह विधि आपको हर बार तैनात / अनुकरण करने के बजाय ब्राउज़र में डिबग और परीक्षण करने की अनुमति देती है।
मैट रे

2
यह बिल्कुल ठीक नहीं है ... कारण जब कीबोर्ड प्रकट होता है तो यह आकार बदल जाएगा (और यह एकमात्र मामला नहीं है)। तो इसके लिए एक बड़ा नहीं!
हेलबाई

2
@ हेलबाई जब कीबोर्ड दिखाई देगा तो फंक्शन को कॉल किया जाएगा, हालाँकि, आप ओरिएंटेशन डिटेक्शन के लिए किस विधि का उपयोग करते हैं, इसके आधार पर यह पता चलेगा कि ओरिएंटेशन बदल नहीं रहा है, जैसा कि window.orientation के साथ होगा। इसलिए मैं अभी भी अपने जवाब के साथ खड़ा हूं।
hndcrftd

1
@ मैंने एक Ipad 4 पर उस पद्धति का उपयोग किया और उस मुद्दे के कारण इसे बदलने के लिए मजबूर किया गया। तो शायद यह कुछ उपकरणों के लिए काम कर रहा है लेकिन सभी के लिए नहीं ..
HellBaby

1
@MattRay आप आसानी से नवीनतम देव टूलकिट के साथ अभिविन्यास परिवर्तनों का परीक्षण कर सकते हैं जो इस तरह के डिवाइस व्यवहार का अनुकरण करने में सक्षम हैं।
कांटूर

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

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

1
आप इसे एक resizeघटना में संलग्न कर सकते हैं । हालाँकि, IIRC, ये प्रश्न कीबोर्ड के साथ सही तरीके से काम नहीं करेंगे।
एडी ५१

12

मैं iOS और Phonegap के लिए बहुत नया हूँ, लेकिन मैं एक इवेंटलिस्ट में जोड़कर ऐसा करने में सक्षम था। मैंने एक ही काम किया (उदाहरण आप संदर्भ का उपयोग करके), और इसे काम करने के लिए नहीं मिला। लेकिन यह चाल करने के लिए लग रहा था:

// 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 समूह की खोज करने का कुछ सौभाग्य हो सकता है

अभिविन्यास का पता लगाने के तरीके के बारे में एक उदाहरण के रूप में मैंने पढ़ा था पाई गाई: ( खेल , जेएस फ़ाइल) )। यह आपके द्वारा पोस्ट किए गए कोड के समान है, लेकिन आप की तरह ... मैं इसे काम नहीं कर सका।

एक चेतावनी: इवेंटलिस्ट मेरे लिए काम करता है, लेकिन मुझे यकीन नहीं है कि यह एक अत्यधिक गहन दृष्टिकोण है। अब तक यह एकमात्र तरीका है जो मेरे लिए काम कर रहा है, लेकिन मुझे नहीं पता कि क्या बेहतर, अधिक सुव्यवस्थित तरीके हैं।


अद्यतन कोड ऊपर तय किया, यह अब काम करता है


plese ईवेंट का नाम तय करें
Dan

5

orientationchangeघटना के साथ काम करते समय , मुझे पृष्ठ में तत्वों के सही आयाम प्राप्त करने के लिए एक समय समाप्ति की आवश्यकता थी, लेकिन मैचमीडिया ने ठीक काम किया। मेरा अंतिम कोड:

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

3

मेरा मानना ​​है कि सही उत्तर पहले ही पोस्ट और स्वीकार कर लिया गया है, फिर भी एक मुद्दा है जो मैंने खुद अनुभव किया है और कुछ अन्य लोगों ने यहां उल्लेख किया है।

कुछ प्लेटफार्मों पर, विभिन्न गुणों जैसे कि खिड़की के आयाम ( window.innerWidth, window.innerHeight) और window.orientationसंपत्ति को उस समय तक अपडेट नहीं किया जाएगा, जब घटना "orientationchange"को निकाल दिया गया हो। कई बार, संपत्ति window.orientationहै undefinedकी गोलीबारी के बाद कुछ मिलीसेकंड के लिए"orientationchange" (कम से कम यह 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 बनाऊंगा, जैसा कि मैंने आमतौर पर किया था, लेकिन JSField मेरे लिए काम नहीं कर रहा है और इसके लिए मेरा समर्थन बग बंद कर दिया गया है क्योंकि कोई भी अन्य समान समस्या नहीं बता रहा है। अगर कोई और इसे JSFiddle में बदलना चाहता है, तो कृपया आगे बढ़ें।

धन्यवाद! आशा है कि ये आपकी मदद करेगा!


FYI करें, प्रारंभिक परीक्षण पर, मैंने एक मुद्दा देखा: मैं घड़ी की दिशा में एक दो बार घुमाता हूं और एक अलर्ट ने कहा "लैंडस्केप ओरिएंटेशन: 180" भले ही मेरा डिवाइस एक चित्र के रूप में शारीरिक रूप से उन्मुख था।
मार्सएंडबैक

2

मैंने जो किया था यह रहा:

window.addEventListener('orientationchange', doOnOrientationChange);

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

2

यद्यपि यह प्रश्न केवल फोनगैप और आईओएस उपयोग को संदर्भित करता है, और यद्यपि यह पहले से ही उत्तर दिया गया था, मैं 2019 में जेएस के साथ स्क्रीन अभिविन्यास का पता लगाने के व्यापक प्रश्न में कुछ बिंदु जोड़ सकता हूं:

  1. window.orientationप्रॉपर्टी को एंड्रॉइड ब्राउजर्स द्वारा अपग्रेड और सपोर्ट नहीं किया जाता है । यह एक नई प्रॉपर्टी है जो ओरिएंटेशन के बारे में अधिक जानकारी प्रदान करती है - screen.orientation। लेकिन यह अभी भी प्रायोगिक है और आईओएस सफारी द्वारा समर्थित नहीं है । तो सबसे अच्छा परिणाम प्राप्त करने के लिए आपको संभवतः दो के संयोजन का उपयोग करने की आवश्यकता है const angle = screen.orientation ? screen.orientation.angle : window.orientation:।

  2. जैसा कि @benallansmith ने अपनी टिप्पणी में उल्लेख किया है , window.onorientationchangeघटना से पहले निकाल दिया गया है window.onresize, इसलिए आपको स्क्रीन के वास्तविक आयाम नहीं मिलेंगे, जब तक कि आप ओरिएंटचेंज इवेंट के बाद कुछ देरी न करें।

  3. पुराने मोबाइल ब्राउज़र का समर्थन करने के लिए एक कॉर्डोवा स्क्रीन ओरिएंटेशन प्लगिन है, लेकिन मेरा मानना ​​है कि आजकल इसका उपयोग करने की कोई आवश्यकता नहीं है।

  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ईवेंट को निकाल दिया जाता है जब वर्चुअल कीबोर्ड टॉगल किया जाता है , न कि केवल जब ओरिएंटेशन बदलता है।


1

मुझे यह पता लगाने के लिए यह कोड मिला है कि क्या डिवाइस लैंडस्केप ओरिएंटेशन में है और इस मामले में एक स्प्लैश पेज जोड़ें, जिसमें कहा गया है कि "साइट को देखने के लिए ओरिएंटेशन बदलें"। यह iOS, Android और विंडोज़ फोन पर काम कर रहा है। मुझे लगता है कि यह बहुत उपयोगी है क्योंकि यह काफी सुरुचिपूर्ण है और मोबाइल साइट के लिए एक परिदृश्य दृश्य सेट करने से बचें। कोड बहुत अच्छा काम कर रहा है। केवल एक चीज पूरी तरह से संतोषजनक नहीं है कि अगर कोई पृष्ठ को परिदृश्य में लोड करता है तो स्प्लैश पृष्ठ दिखाई नहीं देता है।

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

-2

निम्नलिखित ने मेरे लिए काम किया:

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अभी अपडेट नहीं हुआ है


-3

मैं iPhone के लिए PhoneGap में एक jQTouch ऐप बना रहा हूं। मैं इस मुद्दे से दिनों से जूझ रहा हूं। मैंने देखा है कि इवोल्यूशनर समाधान ने कुछ समय का सुझाव दिया, लेकिन अभी यह काम नहीं कर पाया।

अंत में मैं एक अलग समाधान के साथ आया। यह मूल रूप से समय-समय पर शरीर की चौड़ाई की जांच करता है। यदि चौड़ाई 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!');
}

8
डिवाइस को 320 या 480 पर कोडित करना भविष्य में काम नहीं करेगा, या वर्तमान हाय-रिस फोन के साथ।
Fresheyeball

1
1) आपको ऐसी onresizeघटना का उपयोग करना चाहिए जो तुरंत आग लग जाएगी, 500 मील के दायरे में नहीं 2) यह कोड एंड्रॉइड-विशिष्ट है, onorientationchangeiPhone 3 के बजाय उपयोग करें ) यदि यह ब्राउज़र में समर्थित है तो टेस्ट करें:"onorientationchange" in window
Dan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.