¿Cómo bloqueo la orientación al modo vertical en una aplicación web para iPhone?

160

Estoy creando una aplicación web para iPhone y quiero bloquear la orientación al modo vertical. ¿es posible? ¿Hay alguna extensión de kit web para hacer esto?

Tenga en cuenta que esta es una aplicación escrita en HTML y JavaScript para Mobile Safari, NO es una aplicación nativa escrita en Objective-C.

Kevin
fuente
1
Todo el motivo para crear una aplicación web y no una aplicación nativa es que puede ser multiplataforma, ¿por qué construirías una aplicación web específica para iPhone? ¿Estás buscando escribir un código adicional para bloquear otros teléfonos?
1
Estoy interesado en una solución que sea para "pantallas pequeñas" y no solo para cosas que son 320px y hechas por Apple.
sheriffderek

Respuestas:

70

Puede especificar estilos CSS en función de la orientación de la ventana gráfica: oriente el navegador con body [orient = "landscape"] o body [orient = "portrait"]

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

Sin embargo...

El enfoque de Apple para este problema es permitir que el desarrollador cambie el CSS en función del cambio de orientación, pero no para evitar la reorientación por completo. Encontré una pregunta similar en otro lugar:

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

Scott Fox
fuente
Gracias, pero ya estoy haciendo esa parte, lo que realmente quiero es evitar que Mobile Safari no cambie de orientación cuando el usuario inclina el teléfono.
Kevin
44
El enfoque de Apple sobre este problema es permitir que el desarrollador cambie el CSS en función del cambio de orientación, pero no para evitar la reorientación por completo. Encontré una pregunta similar en otro lugar: ask.metafilter.com/99784/…
Scott Fox el
2
He visto que algunos sitios muestran un mensaje de solo paisaje que le indica al usuario que este sitio solo se puede ver en orientación vertical, solo una opción más que debe considerar.
Jayden Lawson
97

Esta es una solución bastante hacky, pero al menos es algo (?). La idea es usar una transformación CSS para rotar el contenido de su página al modo cuasi-retrato. Aquí está el código JavaScript (expresado en jQuery) para comenzar:

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

El código espera que todo el contenido de su página viva dentro de un div justo dentro del elemento del cuerpo. Gira ese div 90 grados en modo horizontal, de vuelta al retrato.

Izquierda como ejercicio para el lector: el div gira alrededor de su punto central, por lo que es probable que sea necesario ajustar su posición a menos que sea perfectamente cuadrada.

Además, hay un problema visual poco atractivo. Cuando cambia la orientación, Safari gira lentamente, luego el div de nivel superior se ajusta a 90 grados diferentes. Para aún más diversión, agregue

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

a tu CSS. Cuando el dispositivo gira, Safari lo hace, luego lo hace el contenido de su página. Seductor!

Grumdrig
fuente
3
Grumdrig, eres mi héroe! Este es el consejo relacionado con la aplicación web para iPhone más útil y funcional que he visto en este sitio. ¡Muchas gracias!
noviembre
Antes de leer esta respuesta, estaba a punto de sugerir en los comentarios de respuesta "aceptados" que alguien más debería intentar esto y decirme si funcionó. ¡Estoy realmente contento de que alguien ya lo haya hecho, y que lo haya hecho!
Carril
¿Qué pasa si el div es rectangular? ¿Cuál es la fórmula para establecer correctamente el origen de la transformación? TA
superjos
También puede controlarlo con la opción "Orientación de interfaz compatible" en xCode, en la información de desarrollo de Iphone / iPod. Funcionó bien
Rodrigo Dias
1
¿No podemos rotar el cuerpo directamente? Digamos, $ ("body"). Css ("- webkit-transform",! Portrait? "Rotate (-90deg)": "");
Krsna Chaitanya
39

Esta respuesta aún no es posible, pero la estoy publicando para "generaciones futuras". Con suerte, algún día podremos hacerlo a través de la regla CSS @viewport:

@viewport {
    orientation: portrait;
}

Aquí está la página "¿Puedo usar? (A partir de 2019 solo IE y Edge):
https://caniuse.com/#feat=mdn-css_at-rules_viewport_orientation

Especificaciones (en proceso):
https://drafts.csswg.org/css-device-adapt/#orientation-desc

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

Según la tabla de compatibilidad del navegador MDN y el siguiente artículo, parece que hay cierto soporte en ciertas versiones de IE y Opera:
http://menacingcloud.com/?c=cssViewportOrMetaTag

Esta especificación API de JS también parece relevante:
https://w3c.github.io/screen-orientation/

Asumí eso porque era posible con la propuesta @viewport regla , sería posible al establecer orientationla configuración de la ventana gráfica en una metaetiqueta, pero hasta ahora no he tenido éxito con esto.

Siéntase libre de actualizar esta respuesta a medida que las cosas mejoren.

xdhmoore
fuente
Para el 10/2019, esta nueva característica aún no funciona. Por favor mantenganos informados. Gracias.
RainCast
2
De hecho, ha tomado tanto tiempo que me pregunto si alguna vez lo será. Agregué un enlace a la página "CanIUse".
xdhmoore
gracias. ¿Es usted el propietario de esta función? No entiendo cómo se lanza una nueva función CSS. En mi opinión, la organización css habla con cada uno de los principales propietarios de productos de navegador y les pide que lo apoyen. ¿Quién controla el proceso? Soy muy curioso.
RainCast
Ja, no solo otro desarrollador. Estás buscando el W3C.
xdhmoore
19

El siguiente código se utilizó en nuestro juego 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'); 
});
Andrei Schneider
fuente
¿Cómo calculas esos números para el origen de la transformación?
superjos
3
¡¡¡Advertencia!!! No todos los dispositivos informan los mismos valores de orientación, por lo que no se puede confiar en matthewgifford.com/blog/2011/12/22/…
Rob
6

Se me ocurrió este método CSS único de rotación de la pantalla mediante consultas de medios. Las consultas se basan en los tamaños de pantalla que encontré aquí . 480px parecía ser bueno ya que ninguno / pocos dispositivos tenían más de 480px de ancho o menos de 480px de altura.

@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
    }
}
Cuenta
fuente
+1 buena solución. Tengo un pie de página cuya posición está fijada en la parte inferior. ¿Alguna idea de cómo mostrarlo después de la rotación?
Cybrix
1
¿Qué tal usar (orientación: paisaje) en la consulta de medios en lugar de valores de píxeles específicos? ¿O es necesario definir un valor de píxel exacto?
Justin Putney el
Utilicé un valor de píxel porque debe establecer un valor exacto en el html, que debe coincidir con la altura de la pantalla (cuando está en horizontal, por lo que el ancho de la pantalla). Así que usar orientation: landscapeno funcionaría tan bien en mi ejemplo @JustinPutney
Bill
1
De MDN: "Nota: Este valor no corresponde a la orientación real del dispositivo. Al abrir el teclado virtual en la mayoría de los dispositivos en orientación vertical, la ventana de visualización se ensanchará más de lo que es alto, lo que hará que el navegador use estilos de paisaje en lugar de retrato. "
sheriffderek
2
Orientación @media reglas --- sí. Pensé que eran el camino a seguir hasta que leí esto: developer.mozilla.org/en-US/docs/Web/Guide/CSS/…
sheriffderek
2

Tal vez en un nuevo futuro tendrá una solución lista para usar ...

En mayo de 2015,

Hay una funcionalidad experimental que hace eso.

Pero solo funciona en Firefox 18+, IE11 + y Chrome 38+.

Sin embargo, todavía no funciona en Opera o Safari.

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

Aquí está el código actual para los navegadores compatibles:

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

lockOrientation("landscape-primary");
Fabio Nolasco
fuente
Lo estoy usando en mi código de JavaScript en mi sitio web de WordPress como: screen.lockOrientation ("paisaje"); y no funciona Obtengo: jQuery (...). LockOrientation no es una función. ¿Necesito implementar algún complemento o marco?
Alex Stanese
1

Si bien no puede evitar que el cambio de orientación surta efecto, no puede emular ningún cambio como se indica en otras respuestas.

Primero detecte la orientación o reorientación del dispositivo y, usando JavaScript, agregue un nombre de clase a su elemento de ajuste (en este ejemplo, uso la etiqueta 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();

Luego, si el dispositivo es horizontal, use CSS para establecer el ancho del cuerpo a la altura de la vista y la altura del cuerpo al ancho de la vista. Y configuremos el origen de la transformación mientras estamos en ello.

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

Ahora, reoriente el elemento del cuerpo y deslícelo (traduzca) a su posición.

body.rotation-90 {
  transform: rotate(90deg) translateY(-100%);
}
body.rotation90 {
  transform: rotate(-90deg) translateX(-100%);
}
Reggie Pinkham
fuente
0
// CSS hack to prevent layout breaking in landscape
// e.g. screens larger than 320px  
html {
  width: 320px;
  overflow-x: hidden;
}

Esto, o una solución CSS similar, al menos conservará su diseño si eso es lo que busca.

La solución raíz es tener en cuenta las capacidades del dispositivo en lugar de intentar limitarlas. Si el dispositivo no le permite la limitación adecuada, un simple truco es su mejor opción, ya que el diseño es esencialmente incompleto. Cuanto más simple, mejor.

dgoldston
fuente
0

En café si alguien lo necesita.

    $(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)"
Philip
fuente
0

Inspirado en la respuesta de @ Grumdrig, y debido a que algunas de las instrucciones utilizadas no funcionarían, sugiero el siguiente script si alguien más lo necesita:

    $(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);
    });
Yazid Erman
fuente
0

Tengo un problema similar, pero para hacer un paisaje ... creo que el siguiente código debería hacer el truco:

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

ARibeiro
fuente
-3

Haga clic aquí para ver un tutorial y un ejemplo de trabajo de mi sitio web.

Ya no necesita usar hacks solo para mirar la orientación de la pantalla de jQuery Mobile ni debe usar PhoneGap más, a menos que realmente esté usando PhoneGap.

Para que esto funcione en el año 2015 necesitamos:

  • Cordova (cualquier versión aunque sea superior a la 4.0 es mejor)
  • PhoneGap (incluso puede usar PhoneGap, los complementos son compatibles)

Y uno de estos complementos dependiendo de su versión de Cordova:

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

complemento cordova agregar net.yoik.cordova.plugins.screenorientation

  • complemento cordova agregar cordova-plugin-screen-orientación (Cordova> = 4)

complemento cordova agregar cordova-plugin-screen-orientación

Y para bloquear la orientación de la pantalla solo use esta función:

screen.lockOrientation('landscape');

Para desbloquearlo:

screen.unlockOrientation();

Posibles orientaciones:

  • vertical-primaria La orientación está en el modo vertical primario.

  • retrato-secundario La orientación está en el modo de retrato secundario.

  • landscape-primary La orientación está en el modo horizontal primario.

  • paisaje-secundario La orientación está en el modo paisaje secundario.

  • vertical La orientación es vertical principal o vertical secundaria (sensor).

  • paisaje La orientación es paisaje primario o paisaje secundario (sensor).

Gajotres
fuente