Come posso bloccare l'orientamento alla modalità verticale in un'applicazione Web per iPhone?


160

Sto costruendo un'applicazione Web per iPhone e voglio bloccare l'orientamento in modalità verticale. È possibile? Ci sono delle estensioni del web kit per farlo?

Si prega di notare che questa è un'applicazione scritta in HTML e JavaScript per Mobile Safari, NON è un'applicazione nativa scritta in Objective-C.


1
L'intero motivo della creazione di un'applicazione Web e non di un'app nativa è che può essere multipiattaforma, perché dovresti creare un'app Web specifica per iPhone, stai cercando di scrivere un codice aggiuntivo per bloccare altri telefoni ???


1
Sono interessato a una soluzione che sia per "piccoli schermi" e non solo per cose che sono 320 px e realizzate da Apple.
Sheriffderek,

Risposte:


70

Puoi specificare gli stili CSS in base all'orientamento del viewport: scegli come target il browser con body [orient = "landscape"] o body [orient = "portrait"]

http://www.evotech.net/blog/2007/07/web-development-for-the-iphone/

Però...

L'approccio di Apple a questo problema è quello di consentire allo sviluppatore di modificare il CSS in base alla modifica dell'orientamento, ma non di impedire completamente il riorientamento. Ho trovato una domanda simile altrove:

http://ask.metafilter.com/99784/How-can-I-lock-iPhone-orientation-in-Mobile-Safari


Grazie, ma sto già facendo quella parte, quello che voglio davvero è impedire a Mobile Safari di non cambiare orientamento quando l'utente inclina il telefono.
Kevin,

4
L'approccio di Apple a questo problema per consentire allo sviluppatore di modificare il CSS in base alla modifica dell'orientamento ma non per impedire completamente il riorientamento. Ho trovato una domanda simile altrove: ask.metafilter.com/99784/…
Scott Fox,

2
Ho visto alcuni siti mostrare un messaggio solo orizzontale che indica all'utente che questo sito può essere visualizzato solo con orientamento verticale - solo un'altra opzione da prendere in considerazione.
Jayden Lawson,

97

Questa è una soluzione piuttosto confusa, ma è almeno qualcosa (?). L'idea è di utilizzare una trasformazione CSS per ruotare i contenuti della pagina in modalità quasi verticale. Ecco il codice JavaScript (espresso in jQuery) per iniziare:

$(document).ready(function () {
  function reorient(e) {
    var portrait = (window.orientation % 180 == 0);
    $("body > div").css("-webkit-transform", !portrait ? "rotate(-90deg)" : "");
  }
  window.onorientationchange = reorient;
  window.setTimeout(reorient, 0);
});

Il codice prevede che l'intero contenuto della tua pagina viva all'interno di un div all'interno dell'elemento body. Ruota quel div di 90 gradi in modalità orizzontale, tornando al ritratto.

Lasciato come esercizio al lettore: il div ruota attorno al suo punto centrale, quindi probabilmente la sua posizione dovrà essere regolata a meno che non sia perfettamente quadrata.

Inoltre, c'è un problema visivo poco attraente. Quando cambi orientamento, Safari ruota lentamente, quindi il div di livello superiore scatta a 90 gradi diversi. Per un divertimento ancora maggiore, aggiungi

body > div { -webkit-transition: all 1s ease-in-out; }

al tuo CSS. Quando il dispositivo ruota, quindi Safari, quindi il contenuto della tua pagina. Beguiling!


3
Grumdrig, sei il mio eroe! Questo è il suggerimento più utile e funzionante relativo all'applicazione web per iPhone che abbia mai visto su questo sito. Molte grazie!
noober,

Prima di leggere questa risposta, stavo per suggerire sulla risposta "accettata" dei commenti che qualcuno ELSE avrebbe dovuto provare questo e dirmi se funzionava. Sono davvero contento che qualcuno l'abbia già fatto e che sia così!
Lane,

cosa succede se il div è rettangolare? qual è la formula per impostare correttamente l'origine della trasformazione? TA
superjos

Puoi anche controllarlo con l'opzione "Orientamento dell'interfaccia supportata" su xCode, sotto Informazioni sullo sviluppo di Iphone / iPod. Ha funzionato bene
Rodrigo Dias il

1
non possiamo ruotare direttamente il corpo stesso? Dire, $ ("body"). Css ("- webkit-transform",! Portrait? "Rotate (-90deg)": "");
Krishna Chaitanya,

39

Questa risposta non è ancora possibile, ma la sto pubblicando per "generazioni future". Spero che un giorno saremo in grado di farlo tramite la regola CSS @viewport:

@viewport {
    orientation: portrait;
}

Ecco la pagina "Posso usare" (a partire dal 2019 solo IE e Edge):
https://caniuse.com/#feat=mdn-css_at-rules_viewport_orientation

Spec (in elaborazione):
https://drafts.csswg.org/css-device-adapt/#orientation-desc

MDN:
https://developer.mozilla.org/en-US/docs/Web/CSS/@viewport/orientation

Basato sulla tabella di compatibilità del browser MDN e sul seguente articolo, sembra che ci sia del supporto in alcune versioni di IE e Opera:
http://menacingcloud.com/?c=cssViewportOrMetaTag

Anche questa specifica dell'API JS sembra rilevante:
https://w3c.github.io/screen-orientation/

Avevo ipotizzato che, poiché era possibile con la @viewportregola proposta , sarebbe stato possibile impostare orientationle impostazioni della finestra in un metatag, ma finora non ho avuto successo con questo.

Sentiti libero di aggiornare questa risposta man mano che le cose migliorano.


Entro il 10/2019, questa nuova funzionalità non funzionerà ancora. Per favore, tienici aggiornati. Grazie.
RainCast

2
In effetti è passato così tanto tempo che mi chiedo se lo sarà mai. Ho aggiunto un link alla pagina "CanIUse".
xdhmoore,

grazie. sei il proprietario di questa funzione? Non capisco bene come venga rilasciata una nuova funzionalità CSS. A mio avviso, l'organizzazione CSS parla con ciascuno dei principali proprietari di prodotti browser e chiede loro di supportarlo? Chi controlla il processo? Sono molto curioso.
RainCast,

Non ha solo un altro sviluppatore. Stai cercando il W3C.
xdhmoore,

19

Il seguente codice è stato usato nel nostro gioco HTML5.

$(document).ready(function () {
     $(window)    
          .bind('orientationchange', function(){
               if (window.orientation % 180 == 0){
                   $(document.body).css("-webkit-transform-origin", "")
                       .css("-webkit-transform", "");               
               } 
               else {                   
                   if ( window.orientation > 0) { //clockwise
                     $(document.body).css("-webkit-transform-origin", "200px 190px")
                       .css("-webkit-transform",  "rotate(-90deg)");  
                   }
                   else {
                     $(document.body).css("-webkit-transform-origin", "280px 190px")
                       .css("-webkit-transform",  "rotate(90deg)"); 
                   }
               }
           })
          .trigger('orientationchange'); 
});

come capisci quei numeri per l'origine della trasformazione?
Superjos,

3
Avvertimento!!! Non tutti i dispositivi riportano gli stessi valori per l'orientamento, quindi non si può fare affidamento su matthewgifford.com/blog/2011/12/22/…
Rob,

6

Ho trovato questo metodo CSS unico per ruotare lo schermo usando le query multimediali. Le query si basano sulle dimensioni dello schermo che ho trovato qui . 480 px sembrava essere un bene poiché nessun / pochi dispositivi avevano una larghezza superiore a 480 px o inferiore a 480 px.

@media (max-height: 480px) and (min-width: 480px) and (max-width: 600px) { 
    html{
        -webkit-transform: rotate(-90deg);
           -moz-transform: rotate(-90deg);
            -ms-transform: rotate(-90deg);
             -o-transform: rotate(-90deg);
                transform: rotate(-90deg);
        -webkit-transform-origin: left top;
           -moz-transform-origin: left top;
            -ms-transform-origin: left top;
             -o-transform-origin: left top;
                transform-origin: left top;
        width: 320px; /*this is the iPhone screen width.*/
        position: absolute;
        top: 100%;
            left: 0
    }
}

+1 bella soluzione. Ho un piè di pagina che è la posizione fissa sul fondo. Qualche idea su come visualizzarlo dopo la rotazione?
Cybrix,

1
Che ne dici di usare (orientamento: orizzontale) nella media query invece di valori di pixel specifici? O è necessario definire un valore esatto di pixel?
Justin Putney,

Ho usato un valore in pixel perché è necessario impostare un valore esatto sull'html, che deve corrispondere all'altezza dello schermo (in orizzontale, quindi alla larghezza dello schermo). Quindi usare orientation: landscapenon funzionerebbe così bene nel mio esempio @JustinPutney
Bill

1
Da MDN: "Nota: questo valore non corrisponde all'effettivo orientamento del dispositivo. L'apertura della tastiera virtuale sulla maggior parte dei dispositivi con orientamento verticale farà sì che il viewport diventi più largo di quanto sia alto, facendo sì che il browser utilizzi stili di paesaggio anziché verticale. "
Sheriffderek,

2
Orientamento @media regole --- sì. Pensavo fossero la strada da percorrere fino a quando non ho letto questo: developer.mozilla.org/en-US/docs/Web/Guide/CSS/…
sheriffderek,



2

Forse in un nuovo futuro avrà un sollievo immediato ...

Per quanto riguarda maggio 2015,

c'è una funzionalità sperimentale che lo fa.

Funziona solo su Firefox 18+, IE11 + e Chrome 38+.

Tuttavia, non funziona ancora su Opera o Safari.

https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation#Browser_compatibility

Ecco il codice corrente per i browser compatibili:

var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;

lockOrientation("landscape-primary");

Lo sto usando nel mio codice javascript nel mio sito web wordpress come: screen.lockOrientation ("landscape"); e non funziona. Ottengo: jQuery (...). LockOrientation non è una funzione. Devo implementare qualche plug-in o framework?
Alex Stanese,

1

Sebbene non sia possibile impedire che il cambiamento di orientamento abbia effetto, non è possibile emulare alcun cambiamento come indicato in altre risposte.

Per prima cosa rileva l'orientamento o il riorientamento del dispositivo e, utilizzando JavaScript, aggiungi un nome di classe al tuo elemento di avvolgimento (in questo esempio uso il tag body).

function deviceOrientation() {
  var body = document.body;
  switch(window.orientation) {
    case 90:
      body.classList = '';
      body.classList.add('rotation90');
      break;
    case -90:
      body.classList = '';
      body.classList.add('rotation-90');
      break;
    default:
      body.classList = '';
      body.classList.add('portrait');
      break;
  }
}
window.addEventListener('orientationchange', deviceOrientation);
deviceOrientation();

Quindi, se il dispositivo è orizzontale, utilizzare CSS per impostare la larghezza del corpo all'altezza della finestra e l'altezza del corpo alla larghezza della finestra. E impostiamo l'origine della trasformazione mentre ci siamo.

@media screen and (orientation: landscape) {
  body {
    width: 100vh;
    height: 100vw;
    transform-origin: 0 0;
  }
}

Ora, riorienta l'elemento del corpo e fai scorrere (traduci) in posizione.

body.rotation-90 {
  transform: rotate(90deg) translateY(-100%);
}
body.rotation90 {
  transform: rotate(-90deg) translateX(-100%);
}

0
// CSS hack to prevent layout breaking in landscape
// e.g. screens larger than 320px  
html {
  width: 320px;
  overflow-x: hidden;
}

Questa, o una soluzione CSS simile, almeno manterrà il layout se è quello che stai cercando.

La soluzione di root tiene conto delle capacità del dispositivo piuttosto che tentare di limitarle. Se il dispositivo non ti consente la limitazione appropriata rispetto a un semplice hack, è la soluzione migliore poiché il design è sostanzialmente incompleto. Più semplice è, meglio è.


0

Nel caffè se qualcuno ne ha bisogno.

    $(window).bind 'orientationchange', ->
        if window.orientation % 180 == 0
            $(document.body).css
                "-webkit-transform-origin" : ''
                "-webkit-transform" : ''
        else
            if window.orientation > 0
                $(document.body).css
                    "-webkit-transform-origin" : "200px 190px"
                    "-webkit-transform" : "rotate(-90deg)"
            else
                $(document.body).css
                    "-webkit-transform-origin" : "280px 190px"
                    "-webkit-transform" : "rotate(90deg)"

0

Ispirato alla risposta di @ Grumdrig e poiché alcune delle istruzioni utilizzate non funzionavano, suggerisco il seguente script se necessario da qualcun altro:

    $(document).ready(function () {

      function reorient(e) {
        var orientation = window.screen.orientation.type;
        $("body > div").css("-webkit-transform", (orientation == 'landscape-primary' || orientation == 'landscape-secondary') ? "rotate(-90deg)" : "");
      }
    $(window).on("orientationchange",function(){
        reorient();
    });
      window.setTimeout(reorient, 0);
    });

0

Ho un problema simile, ma per rendere il panorama ... Credo che il codice qui sotto dovrebbe fare il trucco:

//This code consider you are using the fullscreen portrait mode
function processOrientation(forceOrientation) {
  var orientation = window.orientation;
  if (forceOrientation != undefined)
    orientation = forceOrientation;
  var domElement = document.getElementById('fullscreen-element-div');
  switch(orientation) {
    case 90:
      var width = window.innerHeight;
      var height = window.innerWidth;
      domElement.style.width = "100vh";
      domElement.style.height = "100vw";
      domElement.style.transformOrigin="50% 50%";
      domElement.style.transform="translate("+(window.innerWidth/2-width/2)+"px, "+(window.innerHeight/2-height/2)+"px) rotate(-90deg)";
      break;
    case -90:
      var width = window.innerHeight;
      var height = window.innerWidth;
      domElement.style.width = "100vh";
      domElement.style.height = "100vw";
      domElement.style.transformOrigin="50% 50%";
      domElement.style.transform="translate("+(window.innerWidth/2-width/2)+"px, "+(window.innerHeight/2-height/2)+"px) rotate(90deg)";
      break;
    default:
      domElement.style.width = "100vw";
      domElement.style.height = "100vh";
      domElement.style.transformOrigin="";
      domElement.style.transform="";
      break;
  }
}
window.addEventListener('orientationchange', processOrientation);
processOrientation();
<html>
<head></head>
<body style="margin:0;padding:0;overflow: hidden;">
  <div id="fullscreen-element-div" style="background-color:#00ff00;width:100vw;height:100vh;margin:0;padding:0"> Test
  <br>
  <input type="button" value="force 90" onclick="processOrientation(90);" /><br>
  <input type="button" value="force -90" onclick="processOrientation(-90);" /><br>
  <input type="button" value="back to normal" onclick="processOrientation();" />
  </div>
</body>
</html>


-3

Fai clic qui per un tutorial ed esempio di lavoro dal mio sito Web.

Non è più necessario utilizzare gli hack solo per guardare jQuery Mobile Screen Orientation né utilizzare PhoneGap, a meno che non si stia effettivamente utilizzando PhoneGap.

Per far funzionare tutto questo nel 2015 abbiamo bisogno di:

  • Cordova (qualsiasi versione anche se qualcosa di sopra 4.0 è meglio)
  • PhoneGap (puoi persino usare PhoneGap, i plugin sono compatibili)

E uno di questi plugin a seconda della versione di Cordova:

  • net.yoik.cordova.plugins.screenorientation (Cordova <4)

plug-in cordova aggiungere net.yoik.cordova.plugins.screenorientation

  • plug-in cordova aggiungere cordova-plugin-screen-orientamento (Cordova> = 4)

plug-in cordova aggiungere cordova-plugin-orientamento-schermo

E per bloccare l'orientamento dello schermo basta usare questa funzione:

screen.lockOrientation('landscape');

Per sbloccarlo:

screen.unlockOrientation();

Possibili orientamenti:

  • verticale-principale L'orientamento è nella modalità verticale principale.

  • ritratto secondario L'orientamento è nella modalità ritratto secondario.

  • landscape-primary L'orientamento è nella modalità orizzontale principale.

  • orizzontale-orizzontale L'orientamento è in modalità orizzontale secondaria.

  • ritratto L'orientamento è verticale o secondario (sensore).

  • orizzontale L'orientamento è orizzontale o secondario (sensore).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.