Предотвратить изменение ориентации в iOS Safari
Можно ли избежать перехода в альбомную ориентацию в Safari для iOS при повороте устройства?
В iOS Safari есть событие "orentationchange", я попытался перехватить его и отключить поведение по умолчанию, например:
<html>
<head>
<script type="text/javascript">
function changeOrientation(event) {
alert("Rotate");
event.preventDefault();
}
</script>
</head>
<body onorientationchange="changeOrientation(event);">
PAGE CONTENT
</body>
</html>
но при тестировании страницы на моем iPhone, когда я поворачиваю устройство, отображается предупреждение, но вид переключается в альбомную ориентацию. Кажется, что event.preventDefault() не останавливает вращение.
Есть ли способ заблокировать это поведение?
10 ответов
В Mobile Safari нет способа навязать определенную ориентацию; он всегда будет автоматически поворачиваться, когда пользователь поворачивает свое устройство.
Возможно, вы можете отобразить что-то для неподдерживаемых ориентаций, информируя пользователя о том, что ориентации не поддерживаются и что им необходимо повернуть устройство обратно, чтобы использовать ваше веб-приложение.
Джонатан Снук обходит эту проблему. На своих слайдах он показывает, как (вроде) заблокировать портрет (см. Слайды 54 и 55).
Код JS из этих слайдов:
window.addEventListener('orientationchange', function () {
if (window.orientation == -90) {
document.getElementById('orient').className = 'orientright';
}
if (window.orientation == 90) {
document.getElementById('orient').className = 'orientleft';
}
if (window.orientation == 0) {
document.getElementById('orient').className = '';
}
}, true);
и CSS:
.orientleft #shell {
-webkit-transform: rotate(-90deg);
-webkit-transform-origin:160px 160px;
}
.orientright #shell {
-webkit-transform: rotate(90deg);
-webkit-transform-origin:230px 230px;
}
Я пытался заставить это работать для пейзажа на iPhone, но это никогда не выглядело на 100% правильным. Однако я подошел ближе к следующему коду jQueryian. Это будет в рамках функции onready. Также обратите внимание: это было в контексте "сохранено на домашний экран", и я думаю, что это изменило положение источника преобразования.
$(window).bind('orientationchange', function(e, onready){
if(onready){
$(document.body).addClass('portrait-onready');
}
if (Math.abs(window.orientation) != 90){
$(document.body).addClass('portrait');
}
else {
$(document.body).removeClass('portrait').removeClass('portrait-onready');
}
});
$(window).trigger('orientationchange', true); // fire the orientation change event at the start, to make sure
И CSS:
.portrait {
-webkit-transform: rotate(90deg);
-webkit-transform-origin: 200px 190px;
}
.portrait-onready {
-webkit-transform: rotate(90deg);
-webkit-transform-origin: 165px 150px;
}
Надеюсь, что это поможет кому-то приблизиться к желаемому результату...
Хотя вы не можете предотвратить вступление в силу изменения ориентации, вы не можете эмулировать изменения, как указано в других ответах.
Сначала определите ориентацию устройства или переориентацию и, используя 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%);
}
Была предложена спецификация для реализации этой функциональности.
Также смотрите эту ошибку Chromium для получения дополнительной информации (пока неясно, будет ли она реализована в WebKit или Chromium).
Может быть, в новом будущем...
По состоянию на май 2015 года
есть экспериментальная функциональность, которая делает это. Но это работает только на Firefox 18+, IE11+ и Chrome 38+.
Тем не менее, он не работает на Opera или Safari.
https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation
Вот текущий код для совместимых браузеров:
var lockOrientation = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
lockOrientation("landscape-primary");
Следующее решение, похоже, работает на iPhone4, 5, 6 и 6+ с июня 2016 года.
<script>
/**
* we are locking mobile devices orientation to portrait mode only
*/
var devWidth, devHeight;
window.addEventListener('load', function() {
devWidth = screen.width;
devHeight = screen.height;
});
window.addEventListener('orientationchange', function () {
if (devWidth < 768 && (window.orientation === 90 || window.orientation == -90)) {
document.body.style.width = devWidth + 'px';
document.body.style.height = devHeight + 'px';
document.body.style.transform = 'rotate(90deg)';
document.body.style.transformOrigin = ''+(devHeight/2)+'px '+(devHeight/2)+'px';
} else {
document.body.removeAttribute('style');
}
}, true);
</script>
Я думаю, что для нашего случая, когда нам необходимо обеспечить единообразное представление данных, которые мы отображаем на экране для медицинских обследований, поворот экрана устройства не может быть разрешен. Разрабатываем приложение для работы в портрете. Поэтому лучшее решение для использования - это либо заблокировать его, что невозможно сделать через браузер, либо отобразить сообщение об ошибке / сообщение о том, что приложение нельзя использовать, пока ориентация не будет установлена.
Еще не проверял это на iPhone, но вы можете попробовать
screen.orientation.lock('portrait');
screen.orientation.unlock();
Дополнительная информация на MDN
Я тестирую этот способ работы для меня:
@media (orientation: portrait) {
body {
transform: rotate(-90deg);
}
}
Если это возможно (что я не верю, что это так), то я настоятельно рекомендую против этого. Пользователи ненавидят, когда их заставляют просматривать страницы определенным образом. Что если они используют свой iphone в док-станции и не могут вынести его в ландшафтном режиме, не отсоединив его, или что, если они предпочитают альбомную версию клавиатуры, потому что клавиши больше?
Если ваш дизайн требует определенной ориентации, вы можете пересмотреть свой дизайн.