移动网站 - 在方向更改时重置视口

Posted

技术标签:

【中文标题】移动网站 - 在方向更改时重置视口【英文标题】:mobile site - reset the viewport on orientation change 【发布时间】:2012-04-19 21:18:01 【问题描述】:

我有一个 590 像素宽的移动网页。所以我这样设置视口:

<meta name = "viewport" content = "width = 590">

当我第一次以纵向或横向访问页面时 - 它看起来不错。页面完全填满了宽度。但是当我改变方向时,视口不会改变。当我从纵向转到横向时,视口比 590 像素宽,反之亦然。

仅在 Galaxy S2 上测试

【问题讨论】:

【参考方案1】:

这听起来和我遇到的问题一模一样。我找不到统一的答案,所以不得不拼凑起来。

首先,任何在纵向和横向上看起来不同的 CSS 都必须放入它自己的 @media 标记中。将整个类正确地放入每个 @media 选择器中很重要,而不仅仅是不同的位。两个视图共有的 CSS 可以放在顶部。我的设备宽度显示为 580,因此我将截止值设置为 600 - 您可以将其设置为您认为适合您的值。

    // All CSS that is common to both

@media all and (min-device-width:601px)and (orientation:landscape)
    // All CSS for Landscape and Desktop

@media only screen and (max-device-width:600px)and (orientation:portrait)
    // All CSS for Portrait view

接下来是视口设置。我将此代码作为标准放入每个页眉中(尺寸是我的手机纵向尺寸)。它需要那里的元数据,以便 javascript 稍后可以访问它。

<meta name="viewport" id="viewport" content="width=480, initial-scale=0.25, maximum-scale=1.0;" />

最后,当页面检测到手机旋转时,我不得不使用一些 Javascript 重写视口设置(感谢 Vinayak.B Original Article)

    //Code to display on mobiles
    //========================================

    var swidth = window.screen.width;
    //These were the values of my website CSS container for portrait and landscape
    var vpwidth = 480;
    var vlwidth = 960;

    updateOrientation();

    window.addEventListener('orientationchange', updateOrientation, false);

    function updateOrientation() 


      var viewport = document.querySelector("meta[name=viewport]");

      switch (window.orientation) 
        case 0: //portrait
          //set the viewport attributes to whatever you want!
            viewport.setAttribute('content', 'width=' + vpwidth + ', initial-scale=0.25, maximum-scale=1.0;')
          break;
        case 90: case -90: //landscape
          //set the viewport attributes to whatever you want!
            viewport.setAttribute('content', 'width=' + vlwidth + ', initial-scale=0.25, maximum-scale=1.0;')
          break;
        default:
          //set the viewport attributes to whatever you want!
            viewport.setAttribute('content', 'width=' + vpwidth + ', initial-scale=0.25, maximum-scale=1.0;')
          break;
      
        //alert(swidth + ' lead to an initial width of ' + vpwidth + ' and a rotate width of ' + vlwidth);
    

经过几个小时的尝试,这对我有用。出于某种原因,在我的手机上,initial-scale=1 搞砸了,但 0.25 有效?!我希望它对你有用,或者至少提供一个好的起点。

【讨论】:

【参考方案2】:

使用设备宽度:

<meta name = "viewport" content = "width=device-width">

这会处理方向变化。

【讨论】:

但是当我使用设备宽度时,页面第一次无法正确显示。 590px 的框看起来比设备宽度大 哦,我明白了,您想缩放内容以适应您的屏幕。您的页面上是否有比 590px 框更大的东西?尝试不使用视口元标记,只需将其删除即可。 是的,这就是我想要的。我只有 590px div。在没有视口的情况下尝试 - 框不会填满所有宽度 再尝试一件事:通过css将body的最大宽度设置为590px 可能有点晚了,或者您可能已经找到了解决方法,但您可以尝试以下方法: 它将使页面比设备宽度大 120%。如果它有效,只需调整初始比例以使其符合您的要求。【参考方案3】:

遇到同样的问题,这是我的解决方案。

方向改变后重新加载页面,然后根据新方向设置视口变量。

window.onorientationchange = function() 
  /*window.orientation returns a value that indicates whether iPhone is in portrait mode, landscape mode with the screen turned to the
    left, or landscape mode with the screen turned to the right. */
  var orientation = window.orientation;
  switch(orientation) 
    case 0:
        var current = $('body').attr('class');
        if(current != 'ps-active')
            location.reload();
        

        break; 

    case 90:
        var current = $('body').attr('class');
        if(current != 'ps-active')
            location.reload();
        
        break;

    case -90: 
        var current = $('body').attr('class');
        if(current != 'ps-active')
            location.reload();
        
        break;
  



 $(document).ready(function() 
window.onload = function() 
  /*window.orientation returns a value that indicates whether iPhone is in portrait mode, landscape mode with the screen turned to the
    left, or landscape mode with the screen turned to the right. */
  var orientation = window.orientation;
  switch(orientation) 
    case 0:

        viewport = document.querySelector("meta[name=viewport]");
        viewport.setAttribute('content', 'width=device-width; initial-scale=0.2; maximum-scale=1.0; user-scalable=yes;');
        $('.container').show();
        break; 

    case 90:
        viewport = document.querySelector("meta[name=viewport]");
        viewport.setAttribute('content', 'width=device-width; initial-scale=0.4; maximum-scale=1.0; user-scalable=yes;');
        $('.container').show();
        break;

    case -90: 
        viewport = document.querySelector("meta[name=viewport]");
        viewport.setAttribute('content', 'width=device-width; initial-scale=0.4; maximum-scale=1.0; user-scalable=yes;');
        $('.container').show();
        break;
    default:
        $('.container').show();
        break;
  

【讨论】:

【参考方案4】:

这对我有用(在 ios Safari 和 Chrome 中测试)。

我想在纵向模式下强制视口为 400 像素,在横向模式下强制为 600 像素。

var resize = function() 
    $('body').removeClass('landscape').removeClass('portrait').addClass(orientation).css('width', $(window).width() + 'px');


var orientation = null;

var onOrientationChange = function () 
    switch(window.orientation)   
        case -90:
        case 90:
            orientation = 'landscape';
        break; 
        default:
            orientation = 'portrait';
        break;
    

    if(screen.width < 768) 
        if(orientation == 'landscape') 
            var scale = Math.round(screen.height / 600 * 10) / 10;
            $('#meta-viewport').attr('content', 'width=600px, initial-scale='+scale+', maximum-scale='+scale+', minimum-scale='+scale+', user-scalable=no'); // landscape mobile
         else 
            var scale = Math.round(screen.width / 400 * 10) / 10;
            $('#meta-viewport').attr('content', 'width=400px, initial-scale='+scale+', maximum-scale='+scale+', minimum-scale='+scale+', user-scalable=no'); // portrait mobile
        
     else if(screen.width >= 768 && screen.width < 1200) 
        var scale = Math.round(screen.width / 960 * 10) / 10;
        $('#meta-viewport').attr('content', 'width=960px, initial-scale='+scale+', maximum-scale='+scale+', minimum-scale='+scale+', user-scalable=no');
     else if(screen.width >= 1200) 
        $('#meta-viewport').attr('content', 'width=device-width, user-scalable=yes');
    

    resize();


$(document).ready(function() 
    $(window).resize(resize);
    $(window).bind('orientationchange', onOrientationChange);
    onOrientationChange();
);

希望对你有帮助!

【讨论】:

【参考方案5】:

在我的测试中,matchMedia 函数在 android 上运行良好:

var mql = window.matchMedia("(orientation: landscape)");
if (mql.matches) 
  /* The device is currently in landscape orientation */

else 
  /* The device is currently in portrait orientation */

【讨论】:

【参考方案6】:

方向改变后重置视口。这个 JS 可以工作,只要你有

<meta name="viewport/>

var maxWidth = screen.width;
var viewport = document.getElementsByName('viewport')[0];
viewport.setAttribute('content', 'width = ' + maxWidth + ', minimum-scale=1.0, maximum-scale=1.0, user-scalable=no');

【讨论】:

【参考方案7】:

我很确定您只能使用 JS 在 Galaxy 中获取方向变化。 试试下面的 sn-p


来自相关帖子:Orientation change in Android using javascript

function orientation_changed ()

    if ( is_portrait() )
    
        //do something
    
    else if ( is_landscape() )
    
        // do something else
    
    clearTimeout(window.t);
    delete window.t;


window.t = undefined;
window.onorientationchange = function (event)

    window.t = setTimeout('orientation_changed();', 250);


function is_landscape()

    var uagent = navigator.userAgent.toLowerCase();
    if ( uagent.search('ipad') > -1 )
    
        var r = ( window.orientation == 90 || window.orientation == -90 );
    
    else
    
        var r = ( screen.width > screen.height );
    
    return r;

【讨论】:

好的,没关系。但是一旦我检测到方向发生了变化,如何调整视口? html 设置一个类,然后在 CSS 中使用 .portrait 或 .landscape: if ( is_portrait() ) document.getElementTagName("html").setAttribute("class", "portrait "); else if ( is_landscape() ) document.getElementTagName("html").setAttribute("class", "landscape"); 但我不想更改 css。我有一个 590px 的盒子,就是这样。我无法改变。但我想使用设备功能使页面适合屏幕

以上是关于移动网站 - 在方向更改时重置视口的主要内容,如果未能解决你的问题,请参考以下文章

设计 Angularjs Material 移动网站的最佳实践 - 视口问题

在移动设备中更改方向时需要关闭弹出窗口

移动方向更改未应用 CSS

移动网站 - 视口取决于设备宽度

尽管有适当的视口元标记,但网站负载在移动设备上略微放大

如何在支持 CSS3 的网站上支持更多的移动视口宽度并强制移动浏览器使用正确的宽度?