Android 在方向更改时更改视口宽度后如何适应屏幕?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12102235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 09:44:08  来源:igfitidea点击:

How to fit to screen after changing viewport width on orientation change?

javascriptandroidiosmobiletablet

提问by Adam Florin

I need the viewport width for a page to be 950px in landscape and 630px in portrait. These pixel widths are unfortunately inflexible.

我需要页面的视口宽度为横向 950 像素和纵向 630 像素。不幸的是,这些像素宽度不灵活。

I'm adjusting the width of the DOM content based on orientation using CSS media queries.

我正在使用 CSS 媒体查询根据方向调整 DOM 内容的宽度。

I'm listening for orientation change events in JS to resize the viewport on orientation change.

我正在侦听 JS 中的方向更改事件,以在方向更改时调整视口的大小。

Everything looks good on initial page load (portrait or landscape).

在初始页面加载(纵向或横向)时,一切看起来都不错。

However, after an orientation change, Mobile Safari preserves the previous scale setting, instead of fitting the viewport to the screen. A double-tap or two straightens it out. But I need that to be automatic.

但是,在方向更改后,Mobile Safari 会保留之前的比例设置,而不是让视口适合屏幕。双击或两次将其拉直。但我需要它是自动的。

I've attached the source below, and uploaded it to a demo URL.

我在下面附上了源代码,并将其上传到演示URL

Below are screen captures taken after orientation changes: from landscape to portrait, and from portrait to landscape.

以下是方向更改后的屏幕截图:从横向到纵向,从纵向到横向。

How can I force Safari to automatically set the viewport width to the screen width? Or am I going about this all wrong?

如何强制 Safari 自动将视口宽度设置为屏幕宽度?或者我在这一切都错了吗?

Changing the various scale settings in the viewport have not helped. Setting maximum-scale=1.0or initial-scale=1.0appears to override my width, setting widthto device-width(i.e. 1024 or 768 on my iPad 2), leaving dead margin space. Setting minimum-scale=1.0appears to do nothing.

更改视口中的各种比例设置无济于事。设置maximum-scale=1.0initial-scale=1.0似乎践踏我的width,设置widthdevice-width(在我的iPad 2也就是1024或768),不留死的空白。设置minimum-scale=1.0似乎什么都不做。

From landscape to portrait

从横向到纵向

From portrait to landscape

从纵向到横向

<!DOCTYPE html>
<html>
    <head>
      <title>iPad orientation</title>

      <meta name="viewport" content="user-scalable=yes">

      <script src="jquery-1.4.2.min.js" type="text/javascript"></script>

      <script type="text/javascript" charset="utf-8">;
        /**
        * update viewport width on orientation change
        */
        function adapt_to_orientation() {
          // determine new screen_width
          var screen_width;
          if (window.orientation == 0 || window.orientation == 180) {
            // portrait
            screen_width = 630;
          } else if (window.orientation == 90 || window.orientation == -90) {
            // landscape
            screen_width = 950;
          }

          // resize meta viewport
          $('meta[name=viewport]').attr('content', 'width='+screen_width);
        }

        $(document).ready(function() {

          // bind to handler
          $('body').bind('orientationchange', adapt_to_orientation);

          // call now
          adapt_to_orientation();
        });

      </script>
      <style type="text/css" media="screen">
        body {
          margin: 0;
        }
        #block {
          background-color: #333;
          color: #fff;
          font-size: 128px;

          /* landscape */
          width: 950px;
        }
        #block .right {
          float: right
        }
        @media only screen and (orientation:portrait) {
          #block {
            width: 630px;
          }
        }
      </style>
    </head>
    <body>
      <div id="block">
        <div class="right">&rarr;</div>
        <div class="left">&larr;</div>
      </div>
    </body>
</html>

回答by Greg Smith

I had this problem and wrote some JavaScript to fix it. I put it on Github here:

我遇到了这个问题并编写了一些 JavaScript 来修复它。我把它放在 Github 上:

https://github.com/incompl/ios-reorient

https://github.com/incompl/ios-reorient

Here is the code for your convenience:

为了您的方便,这里是代码:

window.document.addEventListener('orientationchange', function() {
  var iOS = navigator.userAgent.match(/(iPad|iPhone|iPod)/g);
  var viewportmeta = document.querySelector('meta[name="viewport"]');
  if (iOS && viewportmeta) {
    if (viewportmeta.content.match(/width=device-width/)) {
      viewportmeta.content = viewportmeta.content.replace(/width=[^,]+/, 'width=1');
    }
    viewportmeta.content = viewportmeta.content.replace(/width=[^,]+/, 'width=' + window.innerWidth);
  }
  // If you want to hide the address bar on orientation change, uncomment the next line
  // window.scrollTo(0, 0);
}, false);

回答by Adam Florin

OK, the answer lay in the *-scaleattributes after all.

好吧,答案归根结底在于*-scale属性。

You can force a specific scale by setting both maximum-scaleand minimum-scaleto the same value. But you have to sacrifice user scaling by setting the meta tag to <meta name='viewport' content='user-scalable=no' />.

您可以通过将maximum-scale和设置minimum-scale为相同的值来强制使用特定比例。但是您必须通过将元标记设置为<meta name='viewport' content='user-scalable=no' />.

Note that the *-scalesettings are relative to the device's screen dimensions—which vary from device to device. Fortunately you can look these up in the screenobject in JS.

请注意,这些*-scale设置与设备的屏幕尺寸有关——因设备而异。幸运的是,您可以screen在 JS中的对象中查找这些内容。

So, if your content width is under 980, your forced scale should be screen_dimension / content_width.

因此,如果您的内容宽度低于 980,则您的强制缩放应该是screen_dimension / content_width.

This updated version of my above JS has made orientation changes work smoothly. Tested on iPhone 4 and iPad 2.

我上面 JS 的这个更新版本使方向更改顺利进行。在 iPhone 4 和 iPad 2 上测试。

    function adapt_to_orientation() {
      var content_width, screen_dimension;

      if (window.orientation == 0 || window.orientation == 180) {
        // portrait
        content_width = 630;
        screen_dimension = screen.width * 0.98; // fudge factor was necessary in my case
      } else if (window.orientation == 90 || window.orientation == -90) {
        // landscape
        content_width = 950;
        screen_dimension = screen.height;
      }

      var viewport_scale = screen_dimension / content_width;

      // resize viewport
      $('meta[name=viewport]').attr('content',
        'width=' + content_width + ',' +
        'minimum-scale=' + viewport_scale + ', maximum-scale=' + viewport_scale);
    }

回答by J?rn Berkefeld

use the wisdom of this post and simply get the width and height of the container of your script (window width&height)... https://stackoverflow.com/a/9049670/818732

使用这篇文章的智慧,只需获取脚本容器的宽度和高度(窗口宽度和高度)... https://stackoverflow.com/a/9049670/818732

using this viewport: target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=nosolved my problems on android AND ios. Note that target-densitydpi will be flagged on ALL other devices but Android but won't do any harm. It'll make sure nothing is scaled automatically.

使用此视口:target-densitydpi=device-dpi, width=device-width, initial-scale=1, user-scalable=no解决了我在 android 和 ios 上的问题。请注意,target-densitydpi 将在除 Android 之外的所有其他设备上标记,但不会造成任何伤害。它将确保不会自动缩放任何内容。

回答by Fabio C.

Had a similar problem with iOS, after some testing ended up with a solution you can find here

iOS 也有类似的问题,经过一些测试最终得到了解决方案,您可以在这里找到

Reset Zoom on iOS after viewport width change

视口宽度更改后在 iOS 上重置缩放

In my solution zoom is disabled but you can freely remove "user-scalable=no" to make it zoomable.

在我的解决方案中,缩放被禁用,但您可以自由删除“user-scalable=no”以使其可缩放。