开发者

iPad layout scales up when rotating from portrait to landscape

开发者 https://www.devze.com 2023-02-20 07:58 出处:网络
I have a added to the \"viewport\" meta tag \"width=device-width,initial-scale=1.0\" and on an iPad the page loads up fine in landscape mode, the i开发者_如何学Got switches nicely to portrait and when

I have a added to the "viewport" meta tag "width=device-width,initial-scale=1.0" and on an iPad the page loads up fine in landscape mode, the i开发者_如何学Got switches nicely to portrait and when I rotate it back to landscape it scales the page up and I have to pinch zoom it back to a 1 scale.

I can fix this by adding the "maximum-scale=1.0, user-scalable=no", but I was wondering if there is a way I could fix this without taking away from the user the ability to zoom in the page.

If you have any suggestions I would love to hear them,

Thanks!


------ Update ------

This is not an issue anymore in iOS7. And there is better fix by Scott Jehl on github scottjehl/iOS-Orientationchange-Fix that works for iOS6.

------ Original answer ------

Jeremy Keith (@adactio) has a good solution for this on his blog Orientation and scale

Keep the Markup scalable

<meta name="viewport" content="width=device-width, initial-scale=1">

Then disable scalability with javascript until gesturestart with this script:

if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
    var viewportmeta = document.querySelector('meta[name="viewport"]');
    if (viewportmeta) {
        viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0';
        document.body.addEventListener('gesturestart', function () {
            viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
        }, false);
    }
}


Scott Jehl came up with a fantastic solution that uses the accelerometer to anticipate orientation changes. This solution is very responsive and does not interfere with zoom gestures.

https://github.com/scottjehl/iOS-Orientationchange-Fix

How it works: This fix works by listening to the device's accelerometer to predict when an orientation change is about to occur. When it deems an orientation change imminent, the script disables user zooming, allowing the orientation change to occur properly, with zooming disabled. The script restores zoom again once the device is either oriented close to upright, or after its orientation has changed. This way, user zooming is never disabled while the page is in use.

Minified source:

/*! A fix for the iOS orientationchange zoom bug. Script by @scottjehl, rebound by @wilto.MIT License.*/(function(m){if(!(/iPhone|iPad|iPod/.test(navigator.platform)&&navigator.userAgent.indexOf("AppleWebKit")>-1)){return}var l=m.document;if(!l.querySelector){return}var n=l.querySelector("meta[name=viewport]"),a=n&&n.getAttribute("content"),k=a+",maximum-scale=1",d=a+",maximum-scale=10",g=true,j,i,h,c;if(!n){return}function f(){n.setAttribute("content",d);g=true}function b(){n.setAttribute("content",k);g=false}function e(o){c=o.accelerationIncludingGravity;j=Math.abs(c.x);i=Math.abs(c.y);h=Math.abs(c.z);if(!m.orientation&&(j>7||((h>6&&i<8||h<8&&i>6)&&j>5))){if(g){b()}}else{if(!g){f()}}}m.addEventListener("orientationchange",f,false);m.addEventListener("devicemotion",e,false)})(this);


Hopefully, this will help ...

<head>

<style type="text/css">
<!--

/*
    I began with the goal to prevent font scaling in Landscape orientation.
    To do this, see: http://stackoverflow.com/questions/2710764/

    Later, I just wanted to magnify font-size for the iPad, leaving
    the iPhone rendering to the css code.  So ...

    (max-device-width:480px) = iphone.css
    (min-device-width:481px) and
        (max-device-width:1024px) and
            (orientation:portrait) = ipad-portrait.css
    (min-device-width:481px) and
        (max-device-width:1024px) and
            (orientation:landscape) = ipad-landscape.css
    (min-device-width:1025px) = ipad-landscape.css

*/

@media only screen and (min-device-width: 481px)
{
    html {
        -webkit-text-size-adjust: 140%;   /* none for no scaling */
    }
}

-->
</style>

</head>


The fix used by jQuery mobile is here

https://github.com/scottjehl/iOS-Orientationchange-Fix

Minified

/*! A fix for the iOS orientationchange zoom bug. Script by @scottjehl, rebound by @wilto.MIT / GPLv2 License.*/(function (a) { function m() { d.setAttribute("content", g), h = !0 } function n() { d.setAttribute("content", f), h = !1 } function o(b) { l = b.accelerationIncludingGravity, i = Math.abs(l.x), j = Math.abs(l.y), k = Math.abs(l.z), (!a.orientation || a.orientation === 180) && (i > 7 || (k > 6 && j < 8 || k < 8 && j > 6) && i > 5) ? h && n() : h || m() } var b = navigator.userAgent; if (!(/iPhone|iPad|iPod/.test(navigator.platform) && /OS [1-5]_[0-9_]* like Mac OS X/i.test(b) && b.indexOf("AppleWebKit") > -1)) return; var c = a.document; if (!c.querySelector) return; var d = c.querySelector("meta[name=viewport]"), e = d && d.getAttribute("content"), f = e + ",maximum-scale=1", g = e + ",maximum-scale=10", h = !0, i, j, k, l; if (!d) return; a.addEventListener("orientationchange", m, !1), a.addEventListener("devicemotion", o, !1) })(this);

Full source

/*! A fix for the iOS orientationchange zoom bug.
 Script by @scottjehl, rebound by @wilto.
 MIT / GPLv2 License.
*/
(function(w){

    // This fix addresses an iOS bug, so return early if the UA claims it's something else.
    var ua = navigator.userAgent;
    if( !( /iPhone|iPad|iPod/.test( navigator.platform ) && /OS [1-5]_[0-9_]* like Mac OS X/i.test(ua) && ua.indexOf( "AppleWebKit" ) > -1 ) ){
        return;
    }

    var doc = w.document;

    if( !doc.querySelector ){ return; }

    var meta = doc.querySelector( "meta[name=viewport]" ),
        initialContent = meta && meta.getAttribute( "content" ),
        disabledZoom = initialContent + ",maximum-scale=1",
        enabledZoom = initialContent + ",maximum-scale=10",
        enabled = true,
        x, y, z, aig;

    if( !meta ){ return; }

    function restoreZoom(){
        meta.setAttribute( "content", enabledZoom );
        enabled = true;
    }

    function disableZoom(){
        meta.setAttribute( "content", disabledZoom );
        enabled = false;
    }

    function checkTilt( e ){
        aig = e.accelerationIncludingGravity;
        x = Math.abs( aig.x );
        y = Math.abs( aig.y );
        z = Math.abs( aig.z );

        // If portrait orientation and in one of the danger zones
        if( (!w.orientation || w.orientation === 180) && ( x > 7 || ( ( z > 6 && y < 8 || z < 8 && y > 6 ) && x > 5 ) ) ){
            if( enabled ){
                disableZoom();
            }           
        }
        else if( !enabled ){
            restoreZoom();
        }
    }

    w.addEventListener( "orientationchange", restoreZoom, false );
    w.addEventListener( "devicemotion", checkTilt, false );

})( this );


This seems to be a bug in iOS 4 which can be remedied with the following Javascript snippet, however it disables the user's ability to do pinch-to-zoom:

https://gist.github.com/901295/229d163414e22ebb14a6a6ba0b9777118f02e52d


This one works !

 <script >
// BUG orientation portrait/lanscape IOS //
if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
var viewportmeta = document.querySelector('meta[name="viewport"]');
if (viewportmeta) {
    viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0';
    document.addEventListener('orientationchange', function () {
        viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1';
    }, false);
  }
}
</script>


In order for the script to work and bypass the 2nd gesture minor tweaking like in orienatation change event set the max to 1.00099 instead of just 1.0


I came up with a different solution to keep the zoom at 1 on rotation, but allow the user to pinch-to-zoom. Basically when the user zooms, javascript changes the viewport zoom level (and the native browser zoom functionality is disabled).

See it here: https://stackoverflow.com/a/11878932/436776


The first fix worked for me with the following changes.

Change initial scale to .8, minimum to .25 and maximum to 1.6.

Use the "meta" tag

<meta name="viewport" content="width=device-width, initial-scale=1">


<script ="text/javascript">
if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
    var viewportmeta = document.querySelector('meta[name="viewport"]');
    if (viewportmeta) {
        viewportmeta.content = 'width=device-width, minimum-scale=.25, maximum-scale=1.6, initial-scale=.8';
        document.body.addEventListener('gesturestart', function () {
            viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
        }, false);
    }
}


When you say it scales the page up, is that all elements, or just the text font size?... For fixing the font size you can use:

html {
    -webkit-text-size-adjust: 100%;
}


to meta:

%meta{content: "width=device-width, initial-scale=1.0, minimum-scale=0.25, maximum-scale=1.6, user-scalable=yes", name: "viewport"}

to global script:

if navigator.platform.toLowerCase() is "ipad"
  viewport = $ "meta[name='viewport']"
  viewport_content = viewport.attr("content")

  # reset initial zoom
  viewport.attr "content", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes"
  setTimeout =>
    viewport.attr "content", viewport_content
  , 0

  # reset zoom on rotate
  timeout = null
  window.onorientationchange = ->
    clearTimeout timeout if timeout?
    viewport.attr "content", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes"
    timeout = setTimeout =>
      viewport.attr "content", viewport_content
    , 1000
0

精彩评论

暂无评论...
验证码 换一张
取 消