在iOS Safari中防止方向变化

时间:2022-08-24 11:08:58

Is it possible to avoid transition to landscape view in Safari for iOS when the device is rotated?

在iOS中,当设备旋转时,是否可以避免在Safari中切换到横向视图?

iOS Safari has the "orentationchange" event, I tried to intercept it and disable the default behavior, like this:

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>

but when testing the page on my iPhone, when I rotate the device the alert is shown, but the view switch to landscape. It seems that event.preventDefault() does not stops the rotation.

但当我在iPhone上测试页面时,当我旋转设备时,会显示警告,但视图会切换到横向。似乎event.preventDefault()不会停止旋转。

Is there a way to block this behavior?

有办法阻止这种行为吗?

8 个解决方案

#1


18  

There is no way to force a particular orientation in Mobile Safari; it'll always autorotate when the user rotates their device.

在移动Safari浏览器中没有办法强制使用特定的方向;当用户旋转他们的设备时,它总是自动的。

Perhaps you can display something for unsupported orientations informing the user that the orientations aren't supported, and that they need to rotate the device back in order to use your web app.

也许您可以显示一些不支持的朝向,通知用户不支持该朝向,并且他们需要将设备旋转回来,以便使用您的web应用程序。

#2


50  

Jonathan Snook has a work around to this problem. In his slides here, he shows how to (sort of) lock to portrait (see slide 54 and 55).

乔纳森·斯努克有一个关于这个问题的研究。在他的幻灯片中,他展示了如何(某种程度上)锁定人像(参见幻灯片54和55)。

The JS code from those slides:

这些幻灯片中的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);

and the CSS:

CSS:

.orientleft #shell {
    -webkit-transform: rotate(-90deg);
    -webkit-transform-origin:160px 160px;
}

.orientright #shell {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin:230px 230px;
} 

I tried to get this working for landscape on the iPhone, but it never looked 100% correct. I came close with the following jQueryian code, however. This would be within the onready function. Also note: this was within a "saved to homescreen" context, and I think that altered the position of the tranform-origin.

我试着让它在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 

And the CSS:

CSS:

.portrait {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin: 200px 190px;
}
.portrait-onready {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin: 165px 150px;
}

Hope that helps someone get close to the desired result...

希望这能帮助人们接近期望的结果……

#3


5  

A spec to implement this functionality has been proposed.

已经提出了实现该功能的规范。

Also, see this Chromium bug for additional information (still unclear whether it will be implemented in WebKit or Chromium).

另外,请参见这个Chromium bug获得更多信息(仍然不清楚它将在WebKit或Chromium中实现)。

#4


5  

While you cannot prevent orientation change from taking effect you can emulate no change as stated in other answers.

虽然你不能阻止方向的改变产生效果,但是你可以模拟其他答案中没有的改变。

First detect device orientation or reorientation and, using JavaScript, add a class name to your wrapping element (in this example I use the body tag).

首先检测设备方向或重定向,然后使用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();

Then if the device is landscape, use CSS to set the body width to the viewport height and the body height to the viewport width. And let’s set the transform origin while we’re at it.

然后,如果设备是横向的,使用CSS将主体宽度设置为viewport高度,将主体高度设置为viewport宽度。我们来设置变换原点。

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

Now, reorient the body element and slide (translate) it into position.

现在,重新定位主体元素并将其滑动到相应的位置。

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

#5


3  

Maybe in a new future...

也许在一个新的未来……

As for May 2015,

2015年5月,

there is an experimental functionality that does that. But it only works on Firefox 18+, IE11+, and Chrome 38+.

有一个实验的功能。但它只适用于Firefox 18+、IE11+和Chrome 38+。

However, it does not work on Opera or Safari yet.

但是,它还不能在Opera或Safari上运行。

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

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

Here is the current code for the compatible browsers:

以下是兼容浏览器的当前代码:

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

lockOrientation("landscape-primary");

#6


1  

I think for our case where we need to provide a consistent view of the data we are displaying on the screen for medical surveys, rotation of the device's screen cannot be allowed. We design the application to work in portrait. So the best solution for use is to either lock it, which can't be done via the browser, or display an error/message indicating the application can't be used until the orientation is fixed.

我认为在我们的情况下,我们需要提供一个一致的视图,我们显示在屏幕上的数据用于医疗调查,不允许设备的屏幕旋转。我们将应用程序设计为纵向工作。因此,最好的解决方案是要么锁定它(通过浏览器无法完成),要么显示一个错误/消息,表明在定位固定之前不能使用应用程序。

#7


1  

The following solution seems working for me on iPhone4, 5, 6, and 6+ as of June 2016.

下面的解决方案在2016年6月的iPhone4、5、6和6+上为我工作。

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

#8


-3  

If it is possible (which I don't believe it is), then I'd strongly advise against it. Users hate being forced into viewing pages in a particular way. What if they're using their iphone in a dock and can't stand it in landscape mode without undocking it, or what if they prefer the landscape version of the keyboard because the keys are bigger?

如果这是可能的(我不相信这是可能的),那么我强烈反对它。用户讨厌*以特定的方式查看页面。如果他们在一个基座上使用iphone,无法在不松开它的情况下在横向模式下运行,或者如果他们更喜欢横向版本的键盘,因为按键更大?

If your design requires a particular orientation then you might want to rethink your design.

如果您的设计需要特定的方向,那么您可能需要重新考虑您的设计。

#1


18  

There is no way to force a particular orientation in Mobile Safari; it'll always autorotate when the user rotates their device.

在移动Safari浏览器中没有办法强制使用特定的方向;当用户旋转他们的设备时,它总是自动的。

Perhaps you can display something for unsupported orientations informing the user that the orientations aren't supported, and that they need to rotate the device back in order to use your web app.

也许您可以显示一些不支持的朝向,通知用户不支持该朝向,并且他们需要将设备旋转回来,以便使用您的web应用程序。

#2


50  

Jonathan Snook has a work around to this problem. In his slides here, he shows how to (sort of) lock to portrait (see slide 54 and 55).

乔纳森·斯努克有一个关于这个问题的研究。在他的幻灯片中,他展示了如何(某种程度上)锁定人像(参见幻灯片54和55)。

The JS code from those slides:

这些幻灯片中的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);

and the CSS:

CSS:

.orientleft #shell {
    -webkit-transform: rotate(-90deg);
    -webkit-transform-origin:160px 160px;
}

.orientright #shell {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin:230px 230px;
} 

I tried to get this working for landscape on the iPhone, but it never looked 100% correct. I came close with the following jQueryian code, however. This would be within the onready function. Also note: this was within a "saved to homescreen" context, and I think that altered the position of the tranform-origin.

我试着让它在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 

And the CSS:

CSS:

.portrait {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin: 200px 190px;
}
.portrait-onready {
    -webkit-transform: rotate(90deg);
    -webkit-transform-origin: 165px 150px;
}

Hope that helps someone get close to the desired result...

希望这能帮助人们接近期望的结果……

#3


5  

A spec to implement this functionality has been proposed.

已经提出了实现该功能的规范。

Also, see this Chromium bug for additional information (still unclear whether it will be implemented in WebKit or Chromium).

另外,请参见这个Chromium bug获得更多信息(仍然不清楚它将在WebKit或Chromium中实现)。

#4


5  

While you cannot prevent orientation change from taking effect you can emulate no change as stated in other answers.

虽然你不能阻止方向的改变产生效果,但是你可以模拟其他答案中没有的改变。

First detect device orientation or reorientation and, using JavaScript, add a class name to your wrapping element (in this example I use the body tag).

首先检测设备方向或重定向,然后使用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();

Then if the device is landscape, use CSS to set the body width to the viewport height and the body height to the viewport width. And let’s set the transform origin while we’re at it.

然后,如果设备是横向的,使用CSS将主体宽度设置为viewport高度,将主体高度设置为viewport宽度。我们来设置变换原点。

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

Now, reorient the body element and slide (translate) it into position.

现在,重新定位主体元素并将其滑动到相应的位置。

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

#5


3  

Maybe in a new future...

也许在一个新的未来……

As for May 2015,

2015年5月,

there is an experimental functionality that does that. But it only works on Firefox 18+, IE11+, and Chrome 38+.

有一个实验的功能。但它只适用于Firefox 18+、IE11+和Chrome 38+。

However, it does not work on Opera or Safari yet.

但是,它还不能在Opera或Safari上运行。

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

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

Here is the current code for the compatible browsers:

以下是兼容浏览器的当前代码:

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

lockOrientation("landscape-primary");

#6


1  

I think for our case where we need to provide a consistent view of the data we are displaying on the screen for medical surveys, rotation of the device's screen cannot be allowed. We design the application to work in portrait. So the best solution for use is to either lock it, which can't be done via the browser, or display an error/message indicating the application can't be used until the orientation is fixed.

我认为在我们的情况下,我们需要提供一个一致的视图,我们显示在屏幕上的数据用于医疗调查,不允许设备的屏幕旋转。我们将应用程序设计为纵向工作。因此,最好的解决方案是要么锁定它(通过浏览器无法完成),要么显示一个错误/消息,表明在定位固定之前不能使用应用程序。

#7


1  

The following solution seems working for me on iPhone4, 5, 6, and 6+ as of June 2016.

下面的解决方案在2016年6月的iPhone4、5、6和6+上为我工作。

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

#8


-3  

If it is possible (which I don't believe it is), then I'd strongly advise against it. Users hate being forced into viewing pages in a particular way. What if they're using their iphone in a dock and can't stand it in landscape mode without undocking it, or what if they prefer the landscape version of the keyboard because the keys are bigger?

如果这是可能的(我不相信这是可能的),那么我强烈反对它。用户讨厌*以特定的方式查看页面。如果他们在一个基座上使用iphone,无法在不松开它的情况下在横向模式下运行,或者如果他们更喜欢横向版本的键盘,因为按键更大?

If your design requires a particular orientation then you might want to rethink your design.

如果您的设计需要特定的方向,那么您可能需要重新考虑您的设计。