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

Sto creando un’applicazione Web per iPhone e voglio bloccare l’orientamento in modalità verticale. È ansible? Ci sono estensioni web-kit per fare questo?

Si noti che questa è un’applicazione scritta in HTML e JavaScript per Mobile Safari, NON è un’applicazione nativa scritta in Objective-C.

Puoi specificare gli stili CSS in base all’orientamento della vista: scegli il browser con il corpo [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 è di consentire allo sviluppatore di modificare il CSS in base al cambiamento di 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

Questa è una soluzione piuttosto hacky, ma è almeno qualcosa (?). L’idea è di usare una trasformazione CSS per ruotare il contenuto della tua pagina in modalità quasi-ritratto. Ecco il codice JavaScript (express 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 si aspetta che l’intero contenuto della tua pagina viva all’interno di un div all’interno dell’elemento body. Ruota tale div a 90 gradi in modalità orizzontale – torna al ritratto.

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

Inoltre, c’è un problema visivo poco attraente. Quando cambi orientamento, Safari ruota lentamente, quindi il div di primo livello scatta a 90 gradi diversi. Per ancora più divertente, aggiungi

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

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

Questa risposta non è ancora ansible, ma la sto postando per “future generazioni”. Speriamo che un giorno saremo in grado di farlo tramite la regola CSS @viewport:

 @viewport { orientation: portrait; } 

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

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

In base alla tabella di compatibilità del browser MDN e al seguente articolo, sembra che vi sia un supporto in alcune versioni di IE e Opera:
http://menacingcloud.com/?c=cssViewportOrMetaTag

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

Avevo pensato che, poiché era ansible con la regola @viewport proposta, che sarebbe stato ansible impostando l’ orientation nelle impostazioni della vista in un meta tag, ma finora non ho avuto successo.

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

Il seguente codice è stato utilizzato 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'); }); 

Mi sono inventato questo metodo solo CSS per ruotare lo schermo usando le query multimediali. Le query sono basate su dimensioni dello schermo che ho trovato qui . 480px sembrava essere un buon numero di dispositivi / pochi avevano più di 480 px di larghezza o meno di 480px di altezza.

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

Screen.lockOrientation() risolve questo problema, anche se il supporto è meno di universale al momento (aprile 2017):

https://www.w3.org/TR/screen-orientation/

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

Mi piace l’idea di dire all’utente di mettere il telefono in modalità verticale. Come è menzionato qui: http://tech.sarathdr.com/featured/prevent-landscape-orientation-of-iphone-web-apps/ … ma utilizzando CSS invece di JavaScript.

Forse in un nuovo futuro avrà una soluzio out-of-the-box …

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"); 
 // CSS hack to prevent layout breaking in landscape // eg screens larger than 320px html { width: 320px; overflow-x: hidden; } 

Questa o una soluzione CSS simile, almeno conserverà il tuo layout se questo è ciò che stai cercando.

La soluzione radice tiene conto delle capacità del dispositivo piuttosto che tentare di limitarle. Se il dispositivo non ti consente la limitazione appropriata di un semplice trucco è la soluzione migliore dato che il design è essenzialmente incompleto. Più semplice è, meglio è.

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

Sebbene non sia ansible impedire che il cambiamento dell’orientamento diventi effettivo, non è ansible emulare alcun cambiamento come indicato in altre risposte.

Per prima cosa rilevi l’orientazione o il riorientamento del dispositivo e, usando JavaScript, aggiungi un nome di class al tuo elemento wrapping (in questo esempio io uso il body tag).

 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, usa CSS per impostare la larghezza del corpo all’altezza del viewport 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%); } 

Ispirato dalla risposta di @ Grumdrig e poiché alcune delle istruzioni usate 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); }); 

Clicca qui per un tutorial e un esempio funzionante dal mio sito web.

Non è più necessario utilizzare gli hack solo per guardare l’orientamento dello schermo di jQuery Mobile né utilizzare PhoneGap più a meno che non utilizzi effettivamente PhoneGap.

Per fare questo lavoro nell’anno 2015 abbiamo bisogno di:

  • Cordova (qualsiasi versione al di sopra del 4.0 è migliore)
  • PhoneGap (puoi usare anche PhoneGap, i plugin sono compatibili)

E uno di questi plugin dipende dalla tua versione di Cordova:

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

plugin cordova aggiungi net.yoik.cordova.plugins.screenorientation

  • cordova plugin aggiungi cordova-plugin-screen-orientation (Cordova> = 4)

cordova plugin aggiungere cordova-plugin-screen-orientation

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

 screen.lockOrientation('landscape'); 

Per sbloccarlo:

 screen.unlockOrientation(); 

Orientamenti possibili:

  • portrait-primary L’orientamento è nella modalità ritratto principale.

  • portrait-secondary L’orientamento è nella modalità portrait secondario.

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

  • landscape-secondary L’orientamento è nella modalità landscape secondaria.

  • ritratto L’orientamento è verticale o verticale (sensore).

  • paesaggio L’orientamento è o paesaggio-primario o paesaggio-secondario (sensore).