【问题标题】:How can I 'page zoom' on mobile browser如何在移动浏览器上“缩放页面”
【发布时间】:2016-10-19 12:06:23
【问题描述】:

有两种类型的缩放。您在移动浏览器上获得的“捏缩放”,其中内容从屏幕边缘消失。以及您在桌面浏览器上获得的“页面缩放”,就像您执行 Ctrl + 时一样。在“页面缩放”之后,页面会重新流动,因此使用响应式布局,您仍然可以看到整个页面宽度。

如何允许用户在移动设备上“缩放页面”?

我认为我的网站标题栏上可能有一个 Zoom + 和 Zoom - 按钮。我想要这个,因为我有一个大多数用户都喜欢的网络应用程序,无论是在桌面浏览器还是移动浏览器上。但是一些能力较差的用户发现该网站在他们的某些移动设备上又小又繁琐。捏缩放的功能(我没有禁用)是一种帮助,但这意味着不断放大和缩小以进行导航。

我已经尝试了涉及 CSS transform: scale(...) 和 HTML <meta name="viewport" ...> 的解决方案,并从 JavaScript 更改这些解决方案。但是这些似乎都具有“捏缩放”效果,而不是我所追求的页面缩放。另外 transform: scale(...) 会导致基于 js/pixelbased 的交互类型出现问题,例如我使用的 draggable。

我还研究了从 JavaScript 更改 CSS 字体大小。但这仅适用于文本,不适用于图像、<div>s 等。

【问题讨论】:

  • @SuperCoolHandsomeGelBoy 我不认为它是 1156278 的副本,因为 transform: scale(...) 是“捏缩放”。此外,transform: scale(...) 会导致基于 js/基于像素的交互类型出现问题,例如我使用的可拖动。
  • 如果想用javascript控制缩放,这需要大量计算,短时间内无法回答

标签: javascript html css mobile zooming


【解决方案1】:

很抱歉回答了我自己的问题,但经过大量修改后,我找到了一种适合我并且似乎适用于大多数网站的方法,因此我认为值得分享:

function zoom(scale) {
    document.body.style.transform = "scale(" + scale + ")";
    document.body.style.transformOrigin = "top left";
    document.body.style.width = (100 / scale) + "%";
    document.body.style.height = (100 / scale) + "%";
};
zoom(1.25);

诀窍是通过缩放变换放大身体,然后减小高度和宽度。减小高度和宽度会使其重新流动并将转换后的内容保留在屏幕上。

我通过将上面的代码粘贴到几个流行网站上的 Chrome Firefox 和 IE 的控制台来测试它。它似乎完美地重新扩展了 amazon.com 和 stackoverflow.com,但不是 gmail。我自己的网络应用需要下面描述的补丁。

更完整的 jQuery 补丁解决方案:

使用上述解决方案(以及在捏缩放之后),当 JavaScript 尝试测量像素位置并使用它们来定位其他元素时会出现问题。这是因为像getBoundingClientRect() 这样的函数返回坐标乘以scale。如果您使用 jQuery .height().width()offset() 等,您会遇到同样的问题;所有 jQuery 文档都说,“当用户缩放页面时,尺寸可能不正确”。

您可以修复像 .width() 这样的 jQuery 方法,以便像使用 scale = 1 查看时一样传递值。

自 jQuery 3.2.0 起编辑: height()、width() 等已修复,不需要下面显示的补丁。但是 offset() 仍然需要补丁,如果您使用 $(window).height() 或 width() 来查找视口的大小,则需要除以比例。

var zoom = (function () {
    var scale = 1, recurLev = 0;
    function alter(fn, adj) {
        var original = $.fn[fn];
        $.fn[fn] = function () {
            var result;
            recurLev += 1;
            try {
                result = original.apply(this, arguments);
            } finally {
                recurLev -= 1;
            }
            if (arguments.length === 0 && recurLev === 0) {
                result = adj(result);
            }
            return result;
        };
    }
    function scalePos(n) { return n / scale; }
    /* Not needed since jQuery 3.2.0
    alter("width", scalePos);
    alter("height", scalePos);
    alter("outerWidth", scalePos);
    alter("outerHeight", scalePos);
    alter("innerWidth", scalePos);
    alter("innerHeight", scalePos);
    */
    alter("offset", function (o) { o.top /= scale; o.left /= scale; return o; });
    return function (s) {
        scale = s;
        document.body.style.transform = "scale(" + scale + ")";
        document.body.style.transformOrigin = "top left";
        document.body.style.width = (100 / scale) + "%";
        document.body.style.height = (100 / scale) + "%";
    };
}());
zoom(1.25);

我发现的唯一其他问题是代码(如拖动和绘图等)使用来自事件的位置,如 mousedowntouchstartmousemovetouchmove 等。我发现你必须缩放 @987654334 @和pageY除以scale

【讨论】:

  • 谢谢。您的第一个修复(只是纯 javascript)在我的桌面上对我很有用,但由于某种原因对移动设备没有影响。知道为什么吗?
【解决方案2】:

如果您可以复制“捏缩放”,那么您可以使用广泛支持的document.body.style.zoom 属性。

尝试在您的控制台中运行它:

document.body.style.zoom = 2;

【讨论】:

  • 这几乎可以满足我在 Chrome 桌面和 Chrome 上的需求,但会导致基于 js/基于像素的交互类型(例如可拖动)出现问题。但是在 Firefox 上它没有效果,在 IE 上它会弄乱 flex 布局。
  • @James 但您是为移动网站设计的,对吧?所以你只需要检查 chrome/safari Android/iOS。但我发现问题在于它还没有完全跨浏览器。
  • 不,我不是专门为移动设备设计的。它可以在任何浏览器上运行。
  • @James 您的确切问题:“我怎样才能允许用户在移动设备上'页面缩放'?”但没关系
【解决方案3】:
  Hi you can try this 
  css:
   div {
    margin: 150px;
    width: 200px;
    height: 100px;
    background-color: yellow;
    border: 1px solid black;
    border: 1px solid black;
    -ms-transform: scale(2,3); /* IE 9 */
    -webkit-transform: scale(2,3); /* Safari */
    transform: scale(2,3); /* Standard syntax */
  }

  Html:
   <div>
This div element is two times of its original width, and three times of its original height.
</div>

【讨论】:

  • 如我的问题所述,transform: scale(...) 解决方案不起作用。如果我将你的风格应用到包裹我整个 &lt;body&gt;&lt;div&gt;,身体的边缘会从屏幕上溢出。
【解决方案4】:

更改所有内容的字体大小?因此,基本上,您定义的每个字体大小都需要使用 em 作为其单位(例如,而不是 px),以便它成为默认字体的一部分。

然后你可以设置body的字体大小(px)来改变所有字体的大小。

function zoomPage(amount) {
  var currentSize = Number(window.getComputedStyle(document.body, null).getPropertyValue('font-size').match(/\d+/));
  console.log(Number(currentSize), amount, (currentSize + amount));
  document.body.style.fontSize = (currentSize + amount) + 'px';
}
body {
  font-size: 20px;
  font-family: sans-serif;
  max-width: 300px;
}

#smaller {
  font-size: 0.5em;
}

.noresize {
  font-size: 20px;
}
<button class="noresize" onclick="zoomPage(1)">+</button><button class="noresize" onclick="zoomPage(-1)">-</button>
<h1>I am big text</h1>
<p>I am <i>smaller</i> text</p>
<p id="smaller">I am even smaller text, even though I am also a paragraph</p>

【讨论】:

  • 你的代码很好地改变了字体大小,但我的 CSS 有很多图像 &lt;div&gt;s 等,大小和定位在 px 大小。我真的希望页面上的所有内容都能一起调整大小,就像桌面浏览器上的 Ctrl +/- 一样。
  • @James 然后指定em 中的所有内容,除了要充当“边界”框的容器宽度。
  • @James 有一种更简单的方法可以做到这一点,但你说你想要回流,所以我假设你希望边界框保持相同的大小。如果您只是想复制手机的无手势捏合缩放,我可以提供另一个答案。
  • @James 那么我不明白,在这种情况下,视口肯定会变成 boudnign 框吗? * 边界
猜你喜欢
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 1970-01-01
  • 2014-07-15
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多