懒人必备的挪动端定宽网页适配计划

本文最初宣布于我的个人博客:品味之味

现在挪动装备的分辨率纷繁复杂。之前仅仅是安卓机具有林林总总的适配题目,现在 iPhone 也具有了三种主流的分辨率,而将来的 iPhone 7 能够又会玩出什么新花样。怎样以不变应万变,用简简单单的几行代码就能够支撑品种繁多的屏幕分辨率呢?本日就给人人引见一种懒人必备的挪动端定宽网页适配要领。

起首看看下面这行代码:

<meta name="viewport" content="width=device-width, user-scalabel=no">

有过挪动端开辟履历的同砚是否是对上面这句代码异常熟习?它能够最常见的相应式设想的 viewport 设置之一,而我本日引见的这类要领也是利用了 meta 标签设置 viewport 来支撑大部份的挪动端屏幕分辨率。

目的

  • 仅仅经由过程设置 <meta name="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 即可。比方:

<!-- for iPhone -->
<meta name="viewport" content="width=320, user-scalable=no" />

如许你的页面在一切的 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 装备上见效。假如对这个被烧毁的属性感兴致,能够看看下面这两个链接:

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

<!-- for Android 4.4+ -->
<meta name="viewport" content="width=320, user-scalable=no" />

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-densitydpiviewport: widthbody width屏幕可视局限宽度
low-dpi (0.75)vWidth <= 320270270
vWidth > 320vWidth*270
medium-dpi (1.0)vWidth <= 360360360
vWidth > 360vWidth*360
high-dpi (1.5)vWidth <= 320540540
320 < vWidth <= 540vWidth*vWidth*
vWidth > 540vWidth*540
device-dpi (2.0)**vWidth <= 320720720
320 < vWidth <= 720vWidth*vWidth*
vWidth > 720vWidth*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。不过须要注重的是,这个属性在部份安卓机型上是无效的哦。

其他参考资料

  1. Supporting Different Screens in Web Apps – Android Developers

  2. Viewport target-densitydpi support is being deprecated

附录 – 测试页面

有兴致的同砚能够拿这个测试页面来测测本身的手机,别忘了改 viewport 哦。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=250, initial-scale=1.5, user-scalable=no">
    <title>Document</title>
    <style>
        body {
            margin: 0;
        }

        div {
            background: #000;
            color: #fff;
            font-size: 30px;
            text-align: center;
        }

        .block {
            height: 50px;
            border-bottom: 4px solid #ccc;
        }

        #first  { width: 100px; }
        #second { width: 200px; }
        #third  { width: 300px; }
        #fourth { width: 320px; }
        #log { font-size: 16px; }
    </style>
</head>
<body>
    <div id="first" class="block">100px</div>
    <div id="second" class="block">200px</div>
    <div id="third" class="block">300px</div>
    <div id="fourth" class="block">320px</div>
    <div id="log"></div>
    <script>
        function log(content) {
            var logContainer = document.getElementById('log');
            var p = document.createElement('p');
            p.textContent = content;
            logContainer.appendChild(p);
        }

        log('body width:' + document.body.clientWidth)
        log(document.querySelector('[name="viewport"]').content)
    </script>
</body>
</html>
    原文作者:JerryZou
    原文地址: https://segmentfault.com/a/1190000004114309
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞