资讯专栏INFORMATION COLUMN

懒人必备的移动端定宽网页适配方案

wenshi11019 / 2606人阅读

摘要:如何以不变应万变,用简简单单的几行代码就能支持种类繁多的屏幕分辨率呢今天就给大家介绍一种懒人必备的移动端定宽网页适配方法。测试设备三星真机三星虚拟机真机的适配比较简单,只需要设置即可。

本文最初发布于我的个人博客:咀嚼之味

如今移动设备的分辨率纷繁复杂。以前仅仅是安卓机拥有各种各样的适配问题,如今 iPhone 也拥有了三种主流的分辨率,而未来的 iPhone 7 可能又会玩出什么新花样。如何以不变应万变,用简简单单的几行代码就能支持种类繁多的屏幕分辨率呢?今天就给大家介绍一种懒人必备的移动端定宽网页适配方法。

首先看看下面这行代码:

有过移动端开发经验的同学是不是对上面这句代码非常熟悉?它可能最常见的响应式设计的 viewport 设置之一,而我今天介绍的这种方法也是利用了 meta 标签设置 viewport 来支持大部分的移动端屏幕分辨率。

目标

仅仅通过配置 使得移动端网站只需要按照固定的宽度设计并实现,就能在任何主流的移动设备上都能看到符合设计稿的页面,包括 Android 4+、iPhone 4+。

测试设备

三星 Note II (Android 4.1.2) - 真机

三星 Note III (Android 4.4.4 - API 19) - Genymotion 虚拟机

iPhone 6 (iOS 9.1) - 真机

iPhone

iPhone 的适配比较简单,只需要设置 width 即可。比如:


这样你的页面在所有的 iPhone 上,无论是 宽 375 像素的 iPhone 6 还是宽 414 像素的 iPhone 6 plus,都能显示出定宽 320 像素的页面。

Android

Android 上的适配被戏称为移动端的 IE,确实存在着很多兼容性问题。Android 以 4.4 版本为一个分水岭,首先说一说相对好处理的 Android 4.4+

Android 4.4+

为了兼容性考虑,Android 4.4 以上抛弃了 target-densitydpi 属性,它只会在 Android 设备上生效。如果对这个被废弃的属性感兴趣,可以看看下面这两个链接:

Support for target-densitydpi is removed from WebKit

Bug 88047 - Remove support for target-densitydpi in the viewport meta tag

我们可以像在 iPhone 上那样设置 width=320 以达到我们想要的 320px 定宽的页面设计。


Android 4.0 ~ 4.3

作为 Android 相对较老的版本,它对 meta 中的 width 属性支持得比较糟糕。以三星 Note II 为例,它的 device-width 是 360px。如果设置 viewport 中的 width (以下简称 vWidth ) 为小于等于 360 的值,则不会有任何作用;而设置 vWidth 为大于 360 的值,也不会使画面产生缩放,而是出现了横向滚动条。

想要对 Android 4.0 ~ 4.3 进行支持,还是不得不借助于页面缩放,以及那个被废除的属性:target-densitydpi

target-densitydpi

target-densitydpi 一共有四种取值:low-dpi (0.75), medium-dpi (1.0), high-dpi (1.5), device-dpi。在 Android 4.0+ 的设备中,device-dpi 一般都是 2.0。我使用手头上的三星 Note II 设备 (Android 4.1.2) 进行了一系列实验,得到了下面这张表格:

target-densitydpi viewport: width body width 屏幕可视范围宽度
low-dpi (0.75) vWidth <= 320 270 270
vWidth > 320 vWidth* 270
medium-dpi (1.0) vWidth <= 360 360 360
vWidth > 360 vWidth* 360
high-dpi (1.5) vWidth <= 320 540 540
320 < vWidth <= 540 vWidth* vWidth*
vWidth > 540 vWidth* 540
device-dpi (2.0)** vWidth <= 320 720 720
320 < vWidth <= 720 vWidth* vWidth*
vWidth > 720 vWidth* 720

vWidth*:指的是与 viewport 中设置的 width 的值相同。

device-dpi (2.0)**:在 Android 4.0+ 的设备中,device-dpi 一般都是 2.0。

首先可以看到 320px 是个特别诡异的临界值,低于这个临界值后就会发生超出我们预期的事情。综合考虑下来,还是采用 target-densitydpi = device-dpi 这一取值。如果你想要以 320px 作为页面的宽度的话,我建议你针对安卓 4.4 以下的版本设置 width=321

如果 body 的宽度超过屏幕可视范围的宽度,就会出现水平的滚动条。这并不是我们期望的结果,所以我们还要用到缩放属性 initial-scale。计算公式如下:

Scale = deviceWidth / vWidth

这样的计算式不得不使用 JS 来实现,最终我们就能得到适配 Android 4.0 ~ 4.3 定宽的代码:

var match,
    scale,
    TARGET_WIDTH = 320;

if (match = navigator.userAgent.match(/Android (d+.d+)/)) {
    if (parseFloat(match[1]) < 4.4) {
        if (TARGET_WIDTH == 320) TARGET_WIDTH++;
        var scale = window.screen.width / TARGET_WIDTH;
        document.querySelector("meta[name="viewport"]").setAttribute("content", "width=" + TARGET_WIDTH + ", initial-scale = " + scale + ", target-densitydpi=device-dpi");
    }
}

其中,TARGET_WIDTH 就是你所期望的宽度,注意这段代码仅在 320-720px 之间有效哦。

缩放中的坑

如果是 iPhone 或者 Android 4.4+ 的机器,在使用 scale 相关的属性时要非常谨慎,包括 initial-scale, maximum-scaleminimum-scale
要么保证 Scale = deviceWidth / vWidth,要么就尽量不用。来看一个例子:

在缩放比不能保证的情况下,即使设置同样的 widthinitial-scale 后,两者的表现也是不一致。具体两种机型采用的策略如何我还没有探索出来,有兴趣的同学可以研究看看。最省事的办法就是在 iPhone 和 Android 4.4+ 上不设置 scale 相关的属性。

总结

结合上面所有的分析,你可以通过下面这段 JS 代码来对所有 iPhone 和 Android 4+ 的手机屏幕进行适配:

var match,
    scale,
    TARGET_WIDTH = 320;

if (match = navigator.userAgent.match(/Android (d+.d+)/)) {
    if (parseFloat(match[1]) < 4.4) {
        if (TARGET_WIDTH == 320) TARGET_WIDTH++;
        var scale = window.screen.width / TARGET_WIDTH;
        document.querySelector("meta[name="viewport"]").setAttribute("content", "width=" + TARGET_WIDTH + ", initial-scale = " + scale + ", target-densitydpi=device-dpi");
    }
} else {
    document.querySelector("meta[name="viewport"]").setAttribute("content", "width=" + TARGET_WIDTH);
}

如果你不希望你的页面被用户手动缩放,你还可以加上 user-scalable=no。不过需要注意的是,这个属性在部分安卓机型上是无效的哦。

其他参考资料

Supporting Different Screens in Web Apps - Android Developers

Viewport target-densitydpi support is being deprecated

附录 - 测试页面

有兴趣的同学可以拿这个测试页面来测测自己的手机,别忘了改 viewport 哦。




    
    
    Document
    


    
100px
200px
300px
320px

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78266.html

相关文章

  • 移动端布局与适配

    摘要:实战之微信钱包腾讯服务界面网格布局是让开发人员设计一个网格并将内容放在这些网格内。对于移动端适配,不同的公司不同的团队有不同的解决方案。栅格系统用于处理页面多终端适配的问题。 grid实战之微信钱包 腾讯服务界面 CSS3网格布局是让开发人员设计一个网格并将内容放在这些网格内。而不是使用浮动制作一个网格,实际上是你将一个元素声明为一个网格容器,并把元素内容置于网格中。 移动端页面适配—...

    Clect 评论0 收藏0
  • 精彩文章大合集- 收藏集 - 掘金

    摘要:发布应用市场的平台抢红包工具红包精灵开源啦掘金红包精灵,如果喜欢,点个开源不易。作者将原素材文章进行了新内容的添加和重新排列,但是因为文章高效的代码编写技巧总结前端掘金本文总结了代码编写技巧,来提升你的和代码。 收藏安卓开发中非常实用优秀的库! 有图有真相! - Android - 掘金本来是打算收藏工具类的,但转念一想,已经有这么多优秀的库了,就没必要再去重复造轮子了,便归纳工作中比...

    ermaoL 评论0 收藏0
  • 构建自适应手机页面

    摘要:从事开发好多年,但是手机页面开发较晚,所以最开始的时候,为了做微信应用的开发,各种饿补,但是为了将设计稿精准的适配在各种尺寸的手机上还是太坑,所以找了些资料后,借鉴了一些成熟的网站,分享出来,欢迎拍砖。 从事PC Web开发好多年,但是手机页面开发较晚,所以最开始的时候,为了做微信应用的开发,各种饿补,但是为了将设计稿精准的适配在各种尺寸的手机上还是太坑,所以找了些资料后,借鉴了一些成...

    itvincent 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<