mobile site - reset the viewport on orientation change

不问归期 提交于 2019-12-01 04:13:50
Pete.K

This sounds exactly like the problem I was having. I couldn't find a consolidated answer so had to piece one together.

First, any CSS that appeared different on portrait and horizontal had to be put into it's own @media tag. It's important to right out the whole class into each @media selector, not just the bits that are different. CSS that is common to both views can got at the top. My device width was showing at 580 so I set the cut-off at 600 - you can set it to what you feel is right for you.

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

Next was the viewport settings. I put this code as standard into each of my page heads (the size is my Mobile Phone Portrait size). It needs the meta there so that the javascript can get to it later.

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

Finally I had to use some Javascript to re-write the viewport settings when the page detected a rotation of the phone (thanks to 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);
    }

After HOURS of trying things out, this is what worked for me. For some reason on my phone, the initial-scale=1 screwed it up but 0.25 worked?! I hope it works for you or at least offers a good starting point.

Use device-width :

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

This handles orientation changes.

Had the same issue, this was my solution.

Reload the page after orientation change, then set viewport variables based on new orientation.

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

This is what worked for me (tested in both iOS Safari and Chrome).

I wanted to force viewport to 400px in portrait mode and to 600px in landscape mode.

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

Hope it helps!

the matchMedia function works really well on Android in my testing:

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

Reset the viewport after orientation change. This JS could work, provided you have

<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');
The John Smith

I'm pretty certain you can only pickup the orientation change in the Galaxy using JS. Try the snippet below.


From a related post: 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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!