zoukankan      html  css  js  c++  java
  • 移动端适配方案进阶

             Web页面做移动端适配,就是在不同尺寸的手机设备上,页面“相对性的达到合理的展示(自适应)”或者“保持统一效果的等比缩放(看起来差不多)”。有几个要点必须要掌握,一个是不同尺寸,一个是清晰,还有一个是合理。为什么强调这几个词当然是有原因的。

    一、目标

    1.  页面布局总是按照一定规则来进行的。但是移动设备却是多种多样的,屏幕尺寸大小不同,分辨率不同,像素比不同,宽高也不同(相应的概念会在后面介绍)。所以要让一套代码适应所有设备,是最棘手的。、

    2.  要保证清晰度,小屏手机和大屏手机用同样的图片,通过缩放效果显示的大小比例是一致的,但是图片放大会失真,高清图缩小预览又浪费。这就需要综合考虑情况了。

    3.  所谓合理展示,指的是不论什么设备都能有原设计稿一样的视觉和体验效果。如果单纯的按照固定的像素px来设置宽高,结果会怎样。要么小屏手机出现滚动条,要么大屏手机有留白。虽说是原样输出,但这并不是设计稿的效果。人家设计稿是全屏完美展示,不能到手机上变成半屏或两屏了。所以说还原设计稿可以理解成等比例缩放。

    二、思考

    我们的目的搞清楚了,但是还是不得不先泼一泼冷水。首先,没有绝对完美的适配方案。不可能让所有设备真正100%还原设计稿。因为设备的宽高比例就不尽相同五花八门,光这一点就没办法解决,比如说你想用同一张图片给正方形和长方形做壁纸,总有一个会被拉伸或是留白。所以目前通用的原则是文字流式,控件弹性,图片等比缩放。借用万能网络上图片展示下效果。

     

    有了目标和大致想法接下来差不多上方案了,为了更好讲解,还得科普几个知识点。

    三、基本概念

            

    屏幕尺寸(inch):手机设备的对角线长度,比如iphone5为4英寸。

    屏幕宽高比:手机的高度与宽度的比例 为16:9

    物理像素(px): 显示器(手机屏幕)上最小的物理显示单元,比如iphone5的物理像素是640*1136

    像素密度(PPI): 表示沿着对角线,每英寸所拥有的物理像素(Pixel)数目,值越低颗粒感越强,超过300人眼很难分辨

    设备独立像素|密度无关像素|逻辑像素(px): 可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。比如iphone5的物理像素是320*568

    像素比(pdr): 物理像素和设备独立像素的对应关系,设备像素比 = 物理像素 / 设备独立像素,比如iphone5的像素比是2。

    以上概念如果一下接受不了自行百度吧。在这里主要解释下pdr,原来的显示设备的pdr都是1,后来引入了高清屏有了retina,这个pdr就出现了。当然是值越高,显示效果越清楚,同时意味着用css控制某个像素的时候,实际上控制的是成倍的物理像素。最简单的例子是用Iphone5截个图,虽然css下最宽只有320px,但是把图片放到电脑上就成了640px了。

    四,深入了解适配下的高清问题

    用多大的图片才能清晰?

    如果在pdr为1的情况下,要显示100*100的图片,用50*50,100*100还是200*200的图片。当然我们都能理解50*50肯定是要排除的。不过,原因是什么我们还需要讨论一下。换个更形象的说法,要用要求的红黄颜料填满2个坑,是要用一种颜料还是2种还是4种。如果用一种颜料同时显示红与黄的效果,那么只能把两种颜料先混合再倒入,结果肯定会失真;如果用两种,分别用红和黄倒入,那么就泾渭分明;如果用4种呢,就得压缩一半塞进去,也就是说红和黄已经被压缩了一半,还会渗进其它颜色才填满。这个时侯,显示效果会失去锐度。所以不论给的图片大了还是小了都不会模糊。

    但是好多设备不是单单的pdr为1,如果等于2的时候,要显示100*100的图片,就需要200*200的图片;如果pdr为3,就要引入300*300的图片,同样有更多像素比的设备,不可能一一满足,因此普通做法是提供2x,3x图片。

    五、适配方案

    终于要讲到方案了,上面也讲到了要实现自适应就是等比例缩放。因此我们想到三种方案。

    一,按百分比设置宽高。可能实现适配效果,缺点是会出现拉伸,模糊,因为设备宽高比不同,高度很难用百分比控制。

    二,viewport缩放

            在页面内可以设置viewport的scale

    属性来控制页面显示比例。类似于放大缩小图片,通过计算设备宽度与设计稿的比例来得出缩放的倍数,最终实现适配效果。为了适配大多数设备并保证清晰度要采用更大分辨率的设计稿,感觉有些浪费资源。

    三、rem相对单位

    因为rem是相对单位,它会以Htm的font-size的大小为基数来计量长度。所以计算设备屏幕宽度与设计稿的比例来动态设备html的font-size,。这样就能在不同设备上等比例来显示。相当于先把屏幕宽度等分成固定的份数,然后再以份数作为单位计量。

    其实现在的适配方案不外乎这么几种,尤其第三种操作起来很方便(后面会附上代码)。不过,阿里团队为了追求清晰度和解决1px的问题又推出了高清适配方案,主要是把像素比考虑进去,结合第二种第三种方案来实现。方法是先用设备宽度与pdr相乘然后取到与设计稿的比例,动态设置html的font-size,最后再根据pdr的值动态设置scale来实现缩放。

    备注:1px问题指的是在使用rem后,会出现像素值为小数的情况,小数位可能会被系统直接忽略掉,出现宽窄不同的现象。

    附普通适配方案(代码摘自网络):

     1 <script type="text/javascript">
     2     new function (){
     3     var _self = this;
     4     _self.width =1080;//设置UI提供的基准尺寸
     5     _self.fontSize = 200;//默认字体大小,使用时除以此参数作为rem,建议取10或100容易计算。为保证谷歌良好适配,320/_self.width*_self.fontSize>12
     6     _self.widthProportion = function(){
     7     var p = (document.body&&
     8       document.body.clientWidth ||
     9       document.getElementsByTagName("html")[0].offsetWidth)/_self.width;
    10       
    11       return p>0.71?0.71:(p<0.3?0.3:p);  //设置安全尺寸最宽768px,最小320px
    12     };
    13     console.log(_self.widthProportion());
    14     _self.changePage = function(){
    15         document.getElementsByTagName("html")[0].setAttribute("style","font-size:"+_self.widthProportion()*_self.fontSize+"px !important");
    16     }
    17     _self.changePage();
    18     window.addEventListener("resize",function(){_self.changePage();},false);
    19     };
    20 
    21 </script>

    高清适配方案(代码摘自网络):

     1 <script>
     2 (function(doc, win, designSize) { //designSize为设计稿的尺寸(宽) 
     3     var docEl = document.documentElement, 
     4     devWidth = docEl.clientWidth > 1080 ? 1080 : docEl.clientWidth,
     5     dpr = devicePixelRatio || 1,
     6     scale = 1 / dpr, 
     7     width = dpr * devWidth, 
     8     resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'onresize', //判断横屏和窗口重置 
     9     recalc = function() { 
    10               var clientWidth = docEl.clientWidth; 
    11               if (!clientWidth) return; 
    12               document.querySelector('meta[name="viewport"]') .setAttribute('content','width=' + width + ', 
    13               initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); 
    14               docEl.style.fontSize = devWidth / (designSize / 100) * dpr + 'px'; 
    15     }; 
    16     if (!doc.addEventListener) return; 
    17     win.addEventListener(resizeEvt, recalc, false); 
    18     doc.addEventListener('DOMContentLoaded', recalc, false); 
    19 })(document, window, 750);
    20 </script>


    参考文章:

    https://segmentfault.com/a/1190000008767416

    http://www.aliued.com/?p=3166

    https://www.jianshu.com/p/07669cb3e7c5

  • 相关阅读:
    python 批量文件重命名
    python 各种转义字符
    python 生成器
    python 迭代器 itertools模块中常用工具函数
    python 内建迭代函数 iter()
    python 迭代器
    python 常用标准库简介
    python 包及其文件的调用
    python 导入模块或函数
    python 手工抛出异常
  • 原文地址:https://www.cnblogs.com/zuoshoupai/p/9538068.html
Copyright © 2011-2022 走看看