如何在iPhone Web应用程序中将方向锁定为纵向模式?


160

我正在构建iPhone Web应用程序,并希望将方向锁定为纵向模式。这可能吗?是否有任何Web-kit扩展程序可以做到这一点?

请注意,这是用HTML和JavaScript编写的适用于Mobile Safari的应用程序,而不是用Objective-C编写的本机应用程序。


1
构建Web应用程序而不是本机应用程序的全部原因是可以跨平台运行,为什么要构建iPhone特定的Web应用程序,您是否打算编写额外的代码来锁定其他手机?


1
我对一种适用于“小屏幕”的解决方案感兴趣,而不仅仅是针对苹果制造的320像素的解决方案。
sheriffderek

Answers:


70

您可以根据视口方向指定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


谢谢,但是,我已经在做那部分了,我真正想要的是防止Mobile Safari在用户倾斜手机时不切换方向。
凯文”

4
Apple解决此问题的方法是允许开发人员根据方向更改来更改CSS,但不能完全防止重新定向。我发现了一个类似的问题在其他地方: ask.metafilter.com/99784/...
斯科特·福克斯

2
我已经看到一些网站显示仅显示横向消息,指示用户只能以纵向查看此网站-这是供您考虑的另一种选择。
杰登·劳森

97

这是一个非常hacky的解决方案,但至少是某些东西(?)。想法是使用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);
});

该代码希望页面的全部内容位于body元素内的div中。它将div在横向模式下旋转90度-回到纵向。

留给读者练习:div围绕其中心点旋转,因此除非完全为正方形,否则可能需要调整其位置。

另外,还有一个引人注目的视觉问题。更改方向时,Safari会缓慢旋转,然后顶级div会捕捉到90度的不同。要获得更多乐趣,请添加

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

到您的CSS。设备旋转时,Safari会旋转,然后页面内容也会旋转。令人着迷!


3
Grumdrig,你是我的英雄!这是我在该网站上见过的最有用,最有效的iPhone Web应用程序相关提示。非常感谢!
2011年

在阅读此答复之前,我将建议在“已接受”的答复评论中建议ELSE有人尝试一下,并告诉我是否可行。我真的很高兴有人已经做到了,而且做到了!

如果div是矩形怎么办?正确设置变换原点的公式是什么?TA
superjos 2012年

您也可以通过ICode / iPod开发信息下xCode上的“支持的接口方向”选项来控制它。运作良好
Rodrigo Dias

1
我们不能直接旋转身体本身吗?说,$(“ body”)。css(“-webkit-transform”,!portrait?“ rotate(-90deg)”:“”);
Krsna Chaitanya 2014年

39

这个答案尚不可能,但是我将其发布给“未来的一代”。希望有一天,我们能够通过CSS @viewport规则执行此操作:

@viewport {
    orientation: portrait;
}

这是“我可以使用”页面(截至2019年仅IE和Edge):https :
//caniuse.com/#feat=mdn-css_at-rules_viewport_orientation

规范(进行中):https :
//drafts.c​​sswg.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规则可以实现,因此可以通过orientationmeta标记的视口设置中进行设置来实现,但是到目前为止,我还没有成功。

随着情况的改善,随时更新此答案。


到10/2019,此新功能尚无法使用。请随时通知我们。谢谢。
RainCast

2
确实,已经花了很长时间,我想知道是否会过去。我已经添加了指向“ CanIUse”页面的链接。
xdhmoore

谢谢。您是此功能的所有者吗?我不太了解如何发布新的CSS功能。以我的猜测,css org与每个主要的浏览器产品所有者进行对话,并要求他们提供支持?谁控制流程?我很好奇。
RainCast

不仅仅是另一个开发人员。您正在寻找W3C。
xdhmoore

19

在我们的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'); 
});

您如何找出转换原点的那些数字?
superjos 2012年

3
警告!!!并非所有设备都报告相同的定向值,因此不能依赖于matthewgifford.com/blog/2011/12/22/…–
罗布

6

我想出了使用媒体查询旋转屏幕的仅CSS方法。这些查询基于我在这里找到的屏幕尺寸。480px似乎不错,因为没有/很少有设备的宽度大于480px或高度小于480px。

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

+1个不错的解决方案。我有一个固定在底部的页脚。知道旋转后如何显示吗?
Cybrix

1
在媒体查询中使用(方向:横向)而不是特定像素值怎么样?还是需要定义确切的像素值?
贾斯汀·普特尼

我使用了像素值,因为您必须在html上设置一个确切的值,该值必须与屏幕高度匹配(横向时-屏幕宽度)。因此,orientation: landscape在我的示例中,使用@JustinPutney效果不好
比尔

1
来自MDN:“注意:此值与实际设备方向不符。以纵向打开大多数设备上的软键盘会导致视口变宽而不是高,从而导致浏览器使用横向样式而不是纵向样式。 ”
sheriffderek 2014年

2
定向@媒体规则---是的。以为他们要走的路,直到我读这个:developer.mozilla.org/en-US/docs/Web/Guide/CSS/...
sheriffderek



2

也许在新的未来,它将有一个开箱即用的解决方案...

至于2015年5月,

有一个实验功能可以做到这一点。

但它仅适用于Firefox 18 +,IE11 +和Chrome 38+。

但是,它尚不适用于Opera或Safari。

https://developer.mozilla.org/zh-CN/docs/Web/API/Screen/lockOrientation#Browser_compatibility

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

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

lockOrientation("landscape-primary");

我在我的wordpress网站的javascript代码中使用它为:screen.lockOrientation(“ landscape”); 它不起作用。我得到:jQuery(...)。lockOrientation不是一个函数。我需要实现任何插件或框架吗?
亚历克斯·斯坦尼斯

1

虽然您不能阻止方向更改生效,但是您不能像其他答案中所述模拟任何更改。

首先检测设备方向或方向,然后使用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.rotation-90 {
  transform: rotate(90deg) translateY(-100%);
}
body.rotation90 {
  transform: rotate(-90deg) translateX(-100%);
}

0
// CSS hack to prevent layout breaking in landscape
// e.g. screens larger than 320px  
html {
  width: 320px;
  overflow-x: hidden;
}

如果您要这样做,则此方法或类似的CSS解决方案至少将保留您的布局。

根本解决方案是考虑设备的功能,而不是试图限制它们。如果设备不允许您进行适当的限制,那么最好的选择就是简单的破解,因为设计基本上是不完整的。越简单越好。


0

如果有人需要喝咖啡。

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

0

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

我有一个类似的问题,但要弄个风景……我相信下面的代码应该可以解决问题:

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


-3

单击此处以获取我网站上的教程和工作示例。

您不再需要仅使用hack来查看jQuery Mobile屏幕方向,也不再需要使用PhoneGap,除非您实际使用的是PhoneGap。

为了在2015年完成这项工作,我们需要:

  • Cordova(任何高于4.0的版本都更好)
  • PhoneGap(您甚至可以使用PhoneGap,插件兼容)

其中一个取决于您的Cordova版本的插件:

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

科尔多瓦插件添加net.yoik.cordova.plugins.screenorientation

  • cordova插件添加cordova-plugin-screen-orientation(Cordova> = 4)

cordova插件添加cordova-plugin-屏幕方向

要锁定屏幕方向,只需使用此功能:

screen.lockOrientation('landscape');

解锁:

screen.unlockOrientation();

可能的方向:

  • portrait-primary方向为主要纵向模式。

  • 纵向辅助 -方向处于辅助纵向模式。

  • landscape-primary方向是在主要横向模式下。

  • 风景二次取向是在二次横向模式。

  • 纵向方向可以是纵向(纵向)或纵向(感应)。

  • 景观方向为主要景观或次要(传感器)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.