如何在移动浏览器上“页面缩放”

Jam*_*mes 4 html javascript css mobile zooming

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

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

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

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

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

Jam*_*mes 7

很抱歉回答我自己的问题,但经过大量修补后,我找到了一种对我有用并且似乎在大多数网站上都有效的方法,所以我认为值得分享:

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);
Run Code Online (Sandbox Code Playgroud)

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

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

带有 jQ​​uery 补丁的完整解决方案:

使用上述解决方案(以及缩放后),当 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);
Run Code Online (Sandbox Code Playgroud)

唯一的其他问题,我发现在代码(如拖动和绘图等),从事件的使用位置一样mousedowntouchstartmousemovetouchmove等我找到你不得不缩减pageX,并pageY通过将它们除以scale