98

アプリを縦向きモードで起動すると、正常に動作します。次に、横向きに回転し、拡大します。ランドスケープモードで正しくスケーリングするには、何かを 2 回ダブルタップする必要があります。最初に完全にズームインし (通常のダブルタップ動作)、もう一度完全にズームアウトします (通常のダブルタップ動作)。 . ズームアウトすると、ランドスケープモードの正しい新しいスケールにズームアウトします。

ポートレートに戻すと、より一貫して機能するようです。つまり、向きが縦向きに戻ったときに縮尺が正しくなるようにズームを処理します。

これがバグかどうかを調べようとしていますか?または、これが JavaScript で修正できるものである場合はどうなりますか?

ビューポートのメタ コンテンツでは、初期スケールを 1.0 に設定していますが、最小または最大スケールを設定していません (また、設定したくありません)。幅をデバイス幅に設定しています。

何か案は?多くの人が解決策を提供してくれることに感謝していることを私は知っています。

4

11 に答える 11

89

Jeremy Keith(@adactio)は、彼のブログでこれに対する優れたソリューションを提供しています。オリエンテーションとスケール

マークアップに最大スケールを設定しないことにより、マークアップをスケーラブルに保ちます。

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

次に、次のスクリプトでスケーラビリティを再度許可するときに、gesturestartまでロード時に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=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);
    }
}

アップデート22-12-2014:
iPad 1ではこれは機能せず、eventlistenerで失敗します。.body削除すると、次のような修正が行われることがわかりました。

document.addEventListener('gesturestart', function() { /* */ });
于 2011-06-16T22:39:16.040 に答える
18

Scott Jehlは、加速度計を使用して向きの変化を予測する素晴らしいソリューションを思いつきました。このソリューションは非常に応答性が高く、ズーム ジェスチャを妨げません。

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

仕組み: この修正は、デバイスの加速度計をリッスンして、向きの変化がいつ発生するかを予測することによって機能します。方向の変更が差し迫っていると判断した場合、スクリプトはユーザーのズームを無効にし、ズームを無効にして方向の変更を適切に実行できるようにします。デバイスが直立に近い向きになるか、向きが変わった後、スクリプトは再びズームを復元します。このようにして、ページの使用中にユーザーのズームが無効になることはありません。

縮小されたソース:

/*! 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);
于 2012-05-10T17:43:04.113 に答える
14

同じ問題があり、 maximum-scale=1.0 を設定するとうまくいきました。

編集:コメントで述べたように、コンテンツが幅解像度を超えている場合を除いて、これによりユーザーのズームが無効になります。前述のように、これは賢明ではないかもしれません。場合によってはそれが望まれることもあります。

ビューポート コード:

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0;">
于 2010-04-30T13:25:48.523 に答える
3

ビューポートで幅を設定している場合:

<meta name = "viewport" content = "width=device-width; initial-scale=1.0;
 maximum-scale=1.0;" />

そして、時々ランダムにズームインする方向を変更します(特に画面上でドラッグしている場合)。これを修正するには、ここで使用した幅を設定しないでください:

<meta id="viewport" name="viewport" content="initial-scale=1.0; user-scalable=0;
minimum-scale=1.0; maximum-scale=1.0" />

これにより、何が起こってもズームが修正され、window.onorientationchange イベントを使用するか、プラットフォームに依存しない (テストに便利な) 場合はwindow.innerWidthメソッドを使用できます。

于 2010-10-13T07:36:02.843 に答える
1

私は自分のプロジェクトでこの機能を使用しています。

function changeViewPort(key, val) {
    var reg = new RegExp(key, "i"), oldval = document.querySelector('meta[name="viewport"]').content;
    var newval = reg.test(oldval) ? oldval.split(/,\s*/).map(function(v){ return reg.test(v) ? key+"="+val : v; }).join(", ") : oldval+= ", "+key+"="+val ;
    document.querySelector('meta[name="viewport"]').content = newval;
}

したがって、EventListener を追加するだけです。

if( /iPad|iPhone|iPod|Android/i.test(navigator.userAgent) ){
    window.addEventListener("orientationchange", function() { 
        changeViewPort("maximum-scale", 1);
        changeViewPort("maximum-scale", 10);
    }
}
于 2015-02-27T02:31:34.230 に答える
1

横向き/縦向きレイアウトの動作デモを作成しましたが、JavaScript なしで動作させるにはズームを無効にする必要があります。

http://matthewjamestaylor.com/blog/ipad-layout-with-landscape-portrait-modes

于 2011-12-01T11:54:45.937 に答える
1

MobileSafari はorientationchange、オブジェクトのイベントをサポートしていwindowます。残念ながら、JavaScript を介してズームを直接制御する方法はないようです。おそらく、ビューポートを制御するタグを動的に作成/変更できますが、metaそれが機能するとは思えません。ページの初期状態にのみ影響します。おそらく、このイベントを使用して、CSS を使用して実際にコンテンツのサイズを変更できます。幸運を!

于 2010-04-01T03:05:51.780 に答える
0

非常に簡単に実装できる修正を見つけました。フォームの完了時に、フォント サイズが 50px のテキスト要素にフォーカスを設定します。テキスト要素が非表示の場合は機能しないようですが、この要素を非表示にすることは、要素の色プロパティを不透明度なしに設定することで簡単に実行できます。

于 2016-10-23T04:50:08.380 に答える
0

Elisabeth メタタグに「id」プロパティを追加することで、ビューポートのコンテンツを動的に変更できます。

<meta name="viewport" id="view" content="user-scalable=yes, width=device-width minimum-scale=1, maximum-scale=1" />

次に、JavaScriptで呼び出すことができます:

document.getElementById("view").setAttribute('content','user-scalable=yes, width=device-width, minimum-scale=1, maximum-scale=10');
于 2011-02-03T12:47:48.940 に答える
0

ネイティブの iOS ズームを無効にし、代わりに JavaScript でズーム機能を実装することで、私が見た他の回避策とは異なる新しい回避策を見つけました。

ズーム/方向の問題に対する他のさまざまな解決策に関する優れた背景は、Sérgio Lopes によるものです: A fix to the有名な iOS zoom bug on orientation change to portrait .

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="viewport" id="viewport" content="user-scalable=no,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" />
    <title>Robocat mobile Safari zoom fix</title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }
        #container {
            -webkit-transform-origin: 0px 0px;
            -webkit-transform: scale3d(1,1,1);
            /* shrink-to-fit needed so can measure width of container http://stackoverflow.com/questions/450903/make-css-div-width-equal-to-contents */
            display: inline-block;
            *display: inline;
            *zoom: 1;
        }
        #zoomfix {
            opacity: 0;
            position: absolute;
            z-index: -1;
            top: 0;
            left: 0;
        }
    </style>
</head>

<body>
    <input id="zoomfix" disabled="1" tabIndex="-1">
    <div id="container">
        <style>
            table {
                counter-reset: row cell;
                background-image: url(http://upload.wikimedia.org/wikipedia/commons/3/38/JPEG_example_JPG_RIP_010.jpg);
            }
            tr {
                counter-increment: row;
            }
            td:before {
                counter-increment: cell;
                color: white;
                font-weight: bold;
                content: "row" counter(row) ".cell" counter(cell);
            }
        </style>
        <table cellspacing="10">
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
            <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td>
        </table>
    </div>

    <script>
    (function() {
        var viewportScale = 1;
        var container = document.getElementById('container');
        var scale, originX, originY, relativeOriginX, relativeOriginY, windowW, windowH, containerW, containerH, resizeTimer, activeElement;
        document.addEventListener('gesturestart', function(event) {
            scale = null;
            originX = event.pageX;
            originY = event.pageY;
            relativeOriginX = (originX - window.pageXOffset) / window.innerWidth;
            relativeOriginY = (originY - window.pageYOffset) / window.innerHeight;
            windowW = window.innerWidth;
            windowH = window.innerHeight;
            containerW = container.offsetWidth;
            containerH = container.offsetHeight;
        });
        document.addEventListener('gesturechange', function(event) {
            event.preventDefault();
            if (originX && originY && event.scale && event.pageX && event.pageY) {
                scale = event.scale;
                var newWindowW = windowW / scale;
                if (newWindowW > containerW) {
                    scale = windowW / containerW;
                }
                var newWindowH = windowH / scale;
                if (newWindowH > containerH) {
                    scale = windowH / containerH;
                }
                if (viewportScale * scale < 0.1) {
                    scale = 0.1/viewportScale;
                }
                if (viewportScale * scale > 10) {
                    scale = 10/viewportScale;
                }
                container.style.WebkitTransformOrigin = originX + 'px ' + originY + 'px';
                container.style.WebkitTransform = 'scale3d(' + scale + ',' + scale + ',1)';
            }
        });
        document.addEventListener('gestureend', function() {
            if (scale && (scale < 0.95 || scale > 1.05)) {
                viewportScale *= scale;
                scale = null;
                container.style.WebkitTransform = '';
                container.style.WebkitTransformOrigin = '';
                document.getElementById('viewport').setAttribute('content', 'user-scalable=no,initial-scale=' + viewportScale + ',minimum-scale=' + viewportScale + ',maximum-scale=' + viewportScale);
                document.body.style.WebkitTransform = 'scale3d(1,1,1)';
                // Without zoomfix focus, after changing orientation and zoom a few times, the iOS viewport scale functionality sometimes locks up (and completely stops working).
                // The reason I thought this hack would work is because showing the keyboard is the only way to affect the viewport sizing, which forces the viewport to resize (even though the keyboard doesn't actually get time to open!).
                // Also discovered another amazing side effect: if you have no meta viewport element, and focus()/blur() in gestureend, zoom is disabled!! Wow!
                var zoomfix = document.getElementById('zoomfix');
                zoomfix.disabled = false;
                zoomfix.focus();
                zoomfix.blur();
                setTimeout(function() {
                    zoomfix.disabled = true;
                    window.scrollTo(originX - relativeOriginX * window.innerWidth, originY - relativeOriginY * window.innerHeight);
                    // This forces a repaint. repaint *intermittently* fails to redraw correctly, and this fixes the problem.
                    document.body.style.WebkitTransform = '';
                }, 0);
            }
        });
    })();
    </script>
</body>
</html>

改善される可能性がありますが、私のニーズでは、私が見た他のすべてのソリューションで発生する主な欠点を回避できます. これまでのところ、iOS4 を搭載した iPad 2 でモバイル Safari を使用してテストしただけです。

focus()/blur() は、向きを変更して数回ズームした後に発生するズーム機能の時折のロックアップを防ぐための回避策です。

document.body.style を設定すると、フルスクリーンの再描画が強制されます。これにより、ズーム後に再描画がひどく失敗するという断続的な問題を回避できます。

于 2012-08-09T07:49:38.157 に答える
-1

これを行う別の方法がありますが、これはうまくいくようです。

  1. メタ タグを設定してビューポートを scale=1 に制限し、ズームを防止します。

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

  2. JavaScript を使用して、メタ タグを 1/2 秒後に変更して、ズームできるようにします。

    setTimeout(function(){ document.querySelector("meta[name=viewport]").setAttribute('content','width=device-width, initial-scale=1');}, 500);

  3. 再び JavaScript を使用して、向きを変更したら、ページをリロードします。

    window.onorientationchange = function(){window.location.reload();};

デバイスの向きを変えるたびに、最初はズームなしでページがリロードされます。しかし、1/2 秒後に、ズーム機能が復元されます。

于 2015-06-19T07:24:46.537 に答える