Как заблокировать ориентацию в портретном режиме в веб-приложении iPhone? - PullRequest
152 голосов
/ 30 июля 2009

Я создаю веб-приложение для iPhone и хочу заблокировать ориентацию в портретном режиме. Это возможно? Существуют ли расширения веб-набора для этого?

Обратите внимание, что это приложение, написанное на HTML и JavaScript для Mobile Safari, это НЕ нативное приложение, написанное на Objective-C.

Ответы [ 13 ]

96 голосов
/ 16 июля 2010

Это довольно хакерское решение, но оно хоть что-то (?). Идея состоит в том, чтобы использовать CSS-трансформацию, чтобы повернуть содержимое вашей страницы в квазипортретный режим. Вот код JavaScript (выраженный в jQuery) для начала:

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

Код ожидает, что все содержимое вашей страницы будет находиться внутри элемента div внутри элемента body. В альбомном режиме он поворачивается на 90 градусов - обратно в портрет.

Оставлено в качестве упражнения для читателя: div вращается вокруг своей центральной точки, поэтому его положение, вероятно, нужно будет отрегулировать, если оно не будет совершенно квадратным.

Кроме того, есть невидимая проблема со зрением. Когда вы меняете ориентацию, Safari вращается медленно, а затем div верхнего уровня привязывается к 90 градусам. Для еще большего удовольствия добавьте

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

на ваш CSS. Когда устройство вращается, то Safari делает, а содержание вашей страницы. Начинка!

69 голосов
/ 30 июля 2009

Вы можете указать стили CSS на основе ориентации области просмотра: Настройте браузер с помощью body [orient = "landscape"] или body [orient = "Portrait"]

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

Однако ...

Подход Apple к этому вопросу заключается в том, чтобы позволить разработчику изменять CSS на основе изменения ориентации, но не полностью предотвращать переориентацию. Я нашел аналогичный вопрос в другом месте:

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

35 голосов
/ 26 августа 2013

Этот ответ пока невозможен, но я выкладываю его для "будущих поколений". Надеемся, что когда-нибудь мы сможем сделать это с помощью правила CSS @viewport:

@viewport {
    orientation: portrait;
}

Спец (в процессе):
https://drafts.csswg.org/css-device-adapt/#orientation-desc

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

Исходя из таблицы совместимости браузера MDN и следующей статьи, похоже, что в некоторых версиях IE и Opera есть некоторая поддержка:
http://menacingcloud.com/?c=cssViewportOrMetaTag

Эта спецификация JS API также выглядит уместно:
https://w3c.github.io/screen-orientation/

Я предполагал, что, поскольку это было возможно с предложенным правилом @viewport, это было бы возможно путем установки orientation в настройках области просмотра в теге meta, но до сих пор я не добился успеха .

Не стесняйтесь обновлять этот ответ по мере улучшения ситуации.

19 голосов
/ 09 декабря 2011

В нашей 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'); 
});
5 голосов
/ 06 марта 2014

Я придумал этот единственный CSS-метод поворота экрана с помощью медиа-запросов. Запросы основаны на размерах экрана , которые я нашел здесь . 480px показалось хорошим, поскольку ни одно / несколько устройств не имели ширину более 480 пикселей или высоту менее 480 пикселей.

@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
    }
}
5 голосов
/ 08 февраля 2014

Screen.lockOrientation() решает эту проблему, хотя поддержка на данный момент не является универсальной (апрель 2017 г.):

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

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

3 голосов
/ 23 августа 2013

Мне нравится идея сказать пользователю, чтобы он переключил свой телефон в портретный режим. Как упомянуто здесь: http://tech.sarathdr.com/featured/prevent-landscape-orientation-of-iphone-web-apps/ ... но используя CSS вместо JavaScript.

2 голосов
/ 13 мая 2015

Может быть, в новом будущем у него будет готовое решение ...

По состоянию на май 2015 года,

есть экспериментальная функциональность, которая делает это.

Но это работает только на Firefox 18+, IE11 + и Chrome 38+.

Тем не менее, он еще не работает в Opera или Safari.

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

Вот текущий код для совместимых браузеров:

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

lockOrientation("landscape-primary");
0 голосов
/ 12 марта 2017

Вдохновленный ответом @ Grumdrig, и поскольку некоторые из использованных инструкций не будут работать, я предлагаю следующий сценарий, если кто-то еще понадобится:

    $(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 голосов
/ 21 декабря 2016

Хотя вы не можете предотвратить вступление в силу изменения ориентации, вы не можете эмулировать изменения, как указано в других ответах.

Сначала определите ориентацию устройства или переориентацию и, используя JavaScript, добавьте имя класса в элемент обтекания (в этом примере я использую тег 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();

Затем, если устройство имеет альбомную ориентацию, используйте CSS, чтобы установить ширину тела в соответствии с высотой области просмотра, а высоту тела - в ширину области просмотра. И давайте установим источник преобразования, пока мы на нем.

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

Теперь переориентируйте элемент body и сдвиньте (переведите) его в нужное положение.

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