阻止移动网页上的设备旋转

Posted

技术标签:

【中文标题】阻止移动网页上的设备旋转【英文标题】:Blocking device rotation on mobile web pages 【发布时间】:2010-08-17 10:37:49 【问题描述】:

当用户使用移动设备以纵向模式访问它时,是否可以在我的页面上检测到(例如使用 javascript),并在用户将手机旋转到横向时停止方向更改?我的页面上有游戏,仅针对纵向显示进行了优化,我不希望它在横向显示。

【问题讨论】:

这不是您可能会喜欢的答案,但我会发现这种行为在移动设备上非常烦人。迎合您的用户。他们希望能够在横向模式下看到屏幕吗?如果是这样,则针对该场景进行设计。 好的,但是我用html5&JS在我的页面上制作了手机游戏,旋转到横向时无法看到整个屏幕。 @MichalBe - 与其阻止旋转,不如检测它,然后向您的用户显示游戏只能在纵向模式下查看的消息? @MrBliz - 呃。很多人认为每个网站都是某种博客。你好?这是 2015 年。响应式设计非常酷,但它不适合成千上万为固定方向设计的 Web 应用和游戏。让复杂的 HTML5 游戏或应用程序在所有方向上运行绝对不是开发人员的“责任”。 用户想要锁定方向的示例:如果网站设计为使用连接到屏幕的操纵杆(模拟触摸)。比如用手机控制遥控车。您不希望屏幕旋转,因此无论设备认为需要 4 个方向中的哪个方向,操纵杆移动的触摸区域都是操纵杆所在的位置。该站点始终可以为用户提供“解锁/解锁”设备方向更改的选项,因此在这种情况下,锁定方向的 API 将提供最佳的用户体验。 【参考方案1】:

新的 API 正在开发中(并且目前可用)!

screen.orientation.lock();   // webkit only

screen.lockOrientation("orientation");

其中“方向”可以是以下任何一种:

人像-主要 - 它表示屏幕处于主要纵向模式时的方向。如果设备保持在其正常位置并且该位置处于纵向,或者如果设备的正常位置处于横向并且保持设备顺时针旋转 90°,则认为屏幕处于其主要纵向模式。正常位置取决于设备。

人像-次要 - 它表示处于辅助纵向模式时屏幕的方向。如果设备从其正常位置保持 180° 并且该位置处于纵向,或者如果设备的正常位置处于横向并且所保持的设备逆时针转动 90°,则认为屏幕处于其辅助纵向模式。正常位置取决于设备。

风景为主 - 它表示屏幕处于主要横向模式时的方向。如果设备保持在其正常位置并且该位置处于横向,或者如果设备的正常位置是纵向并且保持的设备顺时针转动 90°,则认为屏幕处于其主要横向模式。正常位置取决于设备。

横向二级 - 它表示处于辅助横向模式时屏幕的方向。如果所持设备与其正常位置呈 180° 角且该位置为横向,或者如果设备的正常位置为纵向且所持设备逆时针旋转 90°,则认为屏幕处于辅助横向模式。正常位置取决于设备。

肖像 - 它同时代表纵向和纵向。

风景 - 它同时代表景观主要和景观次要。

默认 - 它代表纵向和横向主要取决于设备的自然方向。例如面板分辨率为1280800,默认为横向,如果分辨率为8001280,默认为纵向。

Mozilla 建议在屏幕上添加 lockOrientationUniversal 以使其更加跨浏览器兼容。

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

点击此处了解更多信息(已弃用的 API):https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation


MDN 中的现代 API 文档在这里:https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/lock

【讨论】:

这在android Chrome中好像没有效果 API 已更改(再次)。此处显示为 webkit only 的内容现在是官方 API:w3c.github.io/screen-orientation/#examples Safari (ios) 怎么样? 此答案需要根据新规范更新 Screen.lockOrientation 已弃用。请更新您的答案。【参考方案2】:

在支持 JavaScript 的浏览器中,应该很容易确定屏幕是横向还是纵向模式以及compensate using CSS。为用户提供禁用此选项的选项或至少警告他们设备旋转将无法正常工作可能会有所帮助。

编辑

检测浏览器方向的最简单方法是检查浏览器的宽度与浏览器的高度。这还有一个好处,即您可以知道游戏是否在自然地以横向模式定向的设备上进行(就像 PSP 等一些移动设备一样)。这比尝试禁用设备旋转更有意义。

编辑 2

Daz 展示了如何检测设备方向,但检测方向只是解决方案的一半。如果要反转自动方向更改,您需要将所有内容旋转 90° 或 270°/-90°,例如

$(window).bind('orientationchange resize', function(event)
  if (event.orientation) 
    if (event.orientation == 'landscape') 
      if (window.rotation == 90) 
        rotate(this, -90);
       else 
        rotate(this, 90);
      
    
  
);

function rotate(el, degs) 
  iedegs = degs/90;
  if (iedegs < 0) iedegs += 4;
  transform = 'rotate('+degs+'deg)';
  iefilter = 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+iedegs+')';
  styles = 
    transform: transform,
    '-webkit-transform': transform,
    '-moz-transform': transform,
    '-o-transform': transform,
    filter: iefilter,
    '-ms-filter': iefilter
  ;
  $(el).css(styles);

注意:如果你想在 IE 中旋转任意角度(用于其他目的),你需要使用矩阵变换,例如

rads = degs * Math.PI / 180;
m11 = m22 = Math.cos(rads);
m21 = Math.sin(rads);
m12 = -m21;
iefilter = "progid:DXImageTransform.Microsoft.Matrix("
  + "M11 = " + m11 + ", "
  + "M12 = " + m12 + ", "
  + "M21 = " + m21 + ", "
  + "M22 = " + m22 + ", sizingMethod = 'auto expand')";
styles['filter'] = styles['-ms-filter'] = iefilter;

——或使用CSS Sandpaper。此外,这会将旋转样式应用于窗口对象,我从未实际测试过,也不知道是否有效。您可能需要将样式应用到文档元素。

无论如何,我仍然建议只显示一条消息,要求用户以纵向模式玩游戏。

【讨论】:

您在$(window).bind 函数中遗漏了一个右括号,而在rotation() 函数中多了一个括号 " window.rotation == 90 " 是机器特定的代码吗? @N.K 我认为不同设备的值实际上是不同的。而且,事实上,它甚至不叫window.rotation。我能找到的所有参考资料都是window.orientation。我要么打错字,要么可用的 API 与 7 年前不同。当我有空闲时间时,将不得不解决这个问题并修改代码。 我有一个 React 应用程序。我想在移动设备上保持纵向视图。有没有可能得到一个直接的答案?【参考方案3】:

似乎很奇怪,没有人提出 CSS 媒体查询解决方案:

@media screen and (orientation: portrait) 
  ...

以及使用特定样式表的选项:

<link rel="stylesheet" type="text/css" href="css/style_p.css" media="screen and (orientation: portrait)">

MDN: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Media_queries#orientation

【讨论】:

媒体查询似乎是要走的路 这不是将 UI 隐藏在其他方向吗?理想情况下,UI 将保持首选方向,但不会被隐藏 这只会使用style_p.css 样式表作为纵向,你不应该将它添加到主要的。【参考方案4】:

简单的 Javascript 代码使移动浏览器以纵向或横向显示..

(即使您必须在两个 DIV 中输入两次 html 代码(每种模式一个),可以说这将比使用 javascript 更改样式表加载得更快...

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Mobile Device</title>
<script type="text/javascript">
// Detect whether device supports orientationchange event, otherwise fall back to
// the resize event.
var supportsOrientationChange = "onorientationchange" in window,
    orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";

window.addEventListener(orientationEvent, function() 
    if(window.orientation==0)
    
      document.getElementById('portrait').style.display = '';
      document.getElementById('landscape').style.display = 'none';
    
    else if(window.orientation==90)
    
      document.getElementById('portrait').style.display = 'none';
      document.getElementById('landscape').style.display = '';
    
, false);
</script>
<meta name="HandheldFriendly" content="true" />
<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no" />
</head>
<body>
<div id="portrait" style="width:100%;height:100%;font-size:20px;">Portrait</div>
<div id="landscape" style="width:100%;height:100%;font-size:20px;">Landscape</div>

<script type="text/javascript">
if(window.orientation==0)

  document.getElementById('portrait').style.display = '';
  document.getElementById('landscape').style.display = 'none';

else if(window.orientation==90)

  document.getElementById('portrait').style.display = 'none';
  document.getElementById('landscape').style.display = '';

</script>
</body>
</html>

在 Android HTC Sense 和 Apple iPad 上测试并运行。

【讨论】:

【参考方案5】:

使用新的 CSS3 功能,您可以将页面旋转到与它们旋转相反的方向。抱歉,不支持 IE7。 :(。

var rotate = 0 - window.orientation;
setAttribute("transform:rotate("+rotate+"deg);-ms-transform:rotate("+rotate+"deg);-webkit-transform:rotate("+rotate+"deg)", "style");

【讨论】:

你将如何在代码中实现它? (在 index.html 文件中) @KarlMorrison 在 JavaScript 中 呵呵我真的很喜欢这个修复的邪恶:)【参考方案6】:

您可以使用 screenSize.width 和 screenSize.height 属性并检测宽度 > 高度的时间,然后通过让用户知道或相应地调整您的屏幕来处理这种情况。

但最好的解决方案是@Doozer1979 所说的……为什么要覆盖用户的偏好?

【讨论】:

这里的用户:很多时候,当我的手机从纵向旋转到横向时,这是出乎意料和不受欢迎的。我可能会想出一个我不想使用横向模式的网站列表,如果这些网站锁定了轮播,那对我来说是一件好事。【参考方案7】:

您可以检测到方向变化,但我认为您无法阻止它。

https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html http://articles.sitepoint.com/article/iphone-development-12-tips/2

【讨论】:

【参考方案8】:

#rotate-device 
    width: 100%;
    height: 100%;
    position: fixed;
    z-index: 9999;
    top: 0;
    left: 0;
    background-color: #000;
    background-image: url(/path to img/rotate.png);
    background-size: 100px 100px;
    background-position: center;
    background-repeat: no-repeat;
    display: none;


@media only screen and (max-device-width: 667px) and (min-device-width: 320px) and (orientation: landscape)
	#rotate-device 
		display: block;
	
&lt;div id="rotate-device"&gt;&lt;/div&gt;

【讨论】:

【参考方案9】:

这个解决方案对我有用,它只是在横向时将整个页面旋转 90 度(有效地将屏幕锁定为纵向)。我不能在这里选择其他一些选项,因为我需要支持 Safari。

@media screen and (min-width: 320px) and (max-width: 767px) and (orientation: landscape) 
  html 
    transform: rotate(-90deg);
    transform-origin: left top;
    width: 100vh;
    overflow-x: hidden;
    position: absolute;
    top: 100%;
    left: 0;
  

在这里找到它:https://css-tricks.com/snippets/css/orientation-lock/

【讨论】:

以上是关于阻止移动网页上的设备旋转的主要内容,如果未能解决你的问题,请参考以下文章

如何在其他部件旋转时阻止物体旋转?

html5移动端阻止滚动问题。

阻止视频在移动设备的后台加载

javascript 阻止Google地图在移动设备上拖动

阻止除 iPhone、iPod 和 iPAD 以外的移动设备和台式机

scroll时怎么阻止body页面的滚动