移动站点 - 在方向改变时重置视口

7

我有一个宽度为590像素的移动页面。因此,我设置了以下视口:

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

当我第一次以纵向或横向方式访问页面时,它看起来很好。页面的宽度完全填充。但是当我更改方向时,视口没有改变。当我从纵向变为横向时,视口比590px更宽,反之亦然。

仅在Galaxy S2上进行了测试。

7个回答

6
这听起来很像我遇到的问题。由于找不到综合性的答案,我只能自己拼凑出一个解决方案。
首先,任何在纵向和横向上显示不同的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
}

下一个是视口设置。我将这段代码放入每个页面头部作为标准(大小为我的手机纵向尺寸)。需要在meta中加入它,以便javascript稍后能够获取到它。
<meta name="viewport" id="viewport" content="width=480, initial-scale=0.25, maximum-scale=1.0;" />

最后我不得不使用一些Javascript来重新编写视口设置,当页面检测到手机的旋转时(感谢Vinayak.B 原始文章)。

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

这个可以处理方向变化。


但是当我使用device-width时,页面第一次显示不正确。590像素的框比设备宽度更大。 - Moshe Shaham
哦,我明白了,您想将内容缩放以适应屏幕。您的页面上有比590像素框更大的东西吗?尝试不使用viewport meta标签,只需将其删除即可。 - gabitzish
是的,那就是我想要的。我只有一个宽度为590像素的div。尝试过不使用视口,但是盒子没有填满整个宽度。 - Moshe Shaham
尝试另一种方法:通过CSS将正文的最大宽度设置为590像素。 - gabitzish
1
可能有点晚了,或者你已经找到了解决方法,但你可以尝试这样做:<meta name="viewport" content="width=device-width, initial-scale=1.2"> 这将使页面比设备宽度大120%。如果它有效,只需调整初始缩放比例即可使其适合您的需要。 - Latency
我将initial-scale设置为1,但用户可以交互并更改比例。如果他这样做,我想将其重置,但如果他没有这样做,我想保留它。我无法弄清楚的是缩放量是否大于或小于1。 - gabitzish

1

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

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

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

1

以下是我使用的方法(在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();
});

希望它有所帮助!

0

在方向改变后重置视口。只要您拥有此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');

0

在我的测试中,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 */
}

-1

我非常确定只能使用JS在Galaxy中检测到方向变化。 尝试下面的代码片段


来自相关帖子: 使用JavaScript在Android中进行屏幕方向更改

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

好的,没问题。但是一旦我检测到方向改变了,我该如何调整视口? - Moshe Shaham
将一个类设置到HTML中,然后在CSS中使用.portrait或.landscape: if ( is_portrait() ) { document.getElementTagName("html").setAttribute("class", "portrait"); } else if ( is_landscape() ) { document.getElementTagName("html").setAttribute("class", "landscape"); } - The John Smith
但我不想改变CSS。我有一个590像素的框,就是这样。它不能被改变。但我想利用设备的能力来适应屏幕。 - Moshe Shaham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接