• 关于移动端适配


     

    主要要解决的适配问题有

    1.  元素自适应问题

    2. 文字大小和边框问题

    3. 高清图问题

    4. 1像素问题

    5. 横竖屏显示问题

    我们css中的1px,通常叫做css像素(虚拟像素),物理像素 与虚拟像素的比就称为设备像素比(dpr)

    现在现代浏览器都支持 window.devicePixelRatio

    一.  元素自适应问题

    通过rem解决,rem不仅可以设置字体大小,还可以设置块的宽高,相比与@media,可以支持中间屏幕,且公用一套样式,减少工作量

    二.  文字大小

    对于文字大小,如果没有要求严格还原设计稿,就不要使用rem自动调整大小。原因是:

    ① 在大屏幕下希望看到更多的文字(使用rem,文字在所有屏幕上显示的个数一样,只是大小不一样)

    ② 中文点阵最好在12px, 14px, 16px,使用rem无法避免13px这些

    1
    2
    3
    4
    5
    6
    7
    8
    9
    div {
        font-size: 12px; // 默认写上dpr为1的fontSize
    }
    [data-dpr="2"] div {
        font-size: 24px;
    }
    [data-dpr="3"] div {
        font-size: 36px;
    }

    对于阿里的lib-flexible,是通过判断dpr的值动态给body标签添加font-size属性;原理相似;后面会贴出我修改的源码

    三. 高清图问题

    1. 使用 srcset标签(WebKit最新特性srcset简介)

    <img src="http://g.ald.alicdn.com/bao/uploaded/i1/TB1d6QqGpXXXXbKXXXXXXXXXXXX_!!0-item_pic.jpg_160x160q90.jpg" srcset="http://img01.taobaocdn.com/imgextra/i1/803091114/TB2XhAPaVXXXXXmXXXXXXXXXXXX_!!803091114.jpg 2x, http://gtms04.alicdn.com/tps/i4/TB1wDjWGXXXXXbtXVXX6Cwu2XXX-398-510.jpg_q75.jpg 3x">

    2、使用js自带的 Image 异步加载图片

    复制代码
    <img id="img" data-src1x="xxx@1x.jpg" data-src2x="xxx@2x.jpg" data-src3x="xxx@3x.jpg"/>
    
    var dpr = window.devicePixelRatio;
    if(dpr > 3){
        dpr = 3;
    };
    
    var imgSrc = $('#img').data('src'+dpr+'x');
    var img = new Image();
    img.src = imgSrc;
    img.onload = function(imgObj){
        $('#img').remove().prepend(imgObj);//替换img对象
    };
    复制代码

    3. 背景图片高清解决方法(对于dpr=2,1个css像素对应4个物理像素)

    对于dpr=1,物理像素和css相同,图片高清。但对于dpr=2,导致每个像素点实际上有4倍的普通像素点,反过来说,一个CSS像素点实际分成了四个,这样就造成了颜色只能近似选取,于是,我们看上去就变得模糊了。所以使用2x的图片就刚刚好。。

    但对于dpr=1,如果使用2x的图片,由于一个css像素对应4个物理像素可以选择,这是就会缩小像素采样(Downsampling)

    ①使用media来处理

    复制代码
    /* 普通显示屏(设备像素比例小于等于1)使用1倍的图 */
    .css{
        background-image: url(img_1x.png);
    }
    
    /* 高清显示屏(设备像素比例大于等于2)使用2倍图  */
    @media only screen and (-webkit-min-device-pixel-ratio:2){
        .css{
            background-image: url(img_2x.png);
        }
    }
    
    /* 高清显示屏(设备像素比例大于等于3)使用3倍图  */
    @media only screen and (-webkit-min-device-pixel-ratio:3){
        .css{
            background-image: url(img_3x.png);
        }
    }
    复制代码

    ②使用image-set来处理

    复制代码
    .css {
        background-image: url(1x.png); /*不支持image-set的情况下显示*/
        background: -webkit-image-set(
                url(1x.png) 1x,/* 支持image-set的浏览器的[普通屏幕]下 */
                url(2x.png) 2x,/* 支持image-set的浏览器的[2倍Retina屏幕] */
                url(3x.png) 3x/* 支持image-set的浏览器的[3倍Retina屏幕] */
        );
    }
    复制代码

    四. 1px问题(retina,即视网膜屏幕)

     什么是 1像素问题 ? 我们说的1像素,就是指1CSS像素。问题就是设计师实际了一条线,本来是1像素,但是在有些设备上,用了横竖都是3的物理像素(即:3x3=9像素)来显示这1像素(即:dpr=3),导致在这些设备上,这条线看上去非常粗!

    1. 使用css3的 scaleY(0.5) 来解决

    不过这种方法通常是通过伪类来实现的,所以一个div只能实现两条线,有四周都有的话要创建两个DIV。且只能实现直线问题

    复制代码
    .div:before {
      content: '';
      position: absolute;
      left: 0;
      top: 0;
      bottom: auto;
      right: auto;
      height: 1px;
       100%;
      background-color: #c8c7cc;
      display: block;
      z-index: 15;
      -webkit-transform-origin: 50% 0%;
              transform-origin: 50% 0%;
    }
    @media only screen and (-webkit-min-device-pixel-ratio: 2) {
      .div:before {
        -webkit-transform: scaleY(0.5);
                transform: scaleY(0.5);
      }
    }
    @media only screen and (-webkit-min-device-pixel-ratio: 3) {
      .div:before {
        -webkit-transform: scaleY(0.33);
                transform: scaleY(0.33);
      }
    }
    复制代码

     对于移动端适配,我现在用下列代码

    复制代码
    (function flexible (window, document) {
        var docEl = document.documentElement;
        console.log(docEl);
        var dpr = window.devicePixelRatio || 1;
    
        if( 2 < dpr && dpr < 3){
            dpr = 2;
        }else if( dpr > 3 ) {
            dpr = 3;
        }
        docEl.setAttribute("data-dpr", dpr);
        // adjust body font size
        function setBodyFontSize () {
        if (document.body) {
              document.body.style.fontSize = (12 * dpr) + 'px';
        }
        else {
              document.addEventListener('DOMContentLoaded', setBodyFontSize);
        }
        }
        setBodyFontSize();
    
        // set 1rem = viewWidth / 10
        function setRemUnit () {
            var rem = docEl.clientWidth / 10;
            docEl.style.fontSize = rem + 'px';
        }
    
        setRemUnit();
    
        // reset rem unit on page resize
        window.addEventListener('resize', setRemUnit);
        window.addEventListener('pageshow', function (e) {
            if (e.persisted) {
                  setRemUnit();
            }
        })
        console.log(dpr);
        // detect 0.5px supports
        if (dpr >= 2) {
            var fakeBody = document.createElement('body');
            var testElement = document.createElement('div');
            testElement.style.border = '.5px solid transparent';
            fakeBody.appendChild(testElement)
            docEl.appendChild(fakeBody);
            if (testElement.offsetHeight === 1) {
                  docEl.classList.add('hairlines');//ios7以下,android等其他系统里,0.5px会被显示为0px,是IOS8+,是的话则加上hairlines的类名
            }
            docEl.removeChild(fakeBody);
    
          }
    }(window, document))
    复制代码

    对于解决1px问题,有时直接通过js在meta标签里改页面缩放就能完美解决。。但是本人还是用不惯。

    这种解决方案的原理就是:将页面整体所缩小1/2,又将html根字体扩大了2倍。所以,对于页面上使用rem的元素,等于没有变化,但是使用px的元素,由于页面缩小了1/2,所有元素尺寸就相当于缩小了1/2。对于上面的例子来说,1px就相当于0.5px了。

    https://github.com/amfe/lib-flexible/tree/master(lib-flexible的第一版本)

  • 相关阅读:
    python openpyxl 封装Execl常用操作的方法
    python webdriver grid多节点运行webdriver程序
    url的正则表达式
    基于Erlang VM的函数式编程语言Elixir
    [整理]团队开发效率提升探索一
    FreeBSD应该装gnome3做桌面
    FreeBSD pkg仓库有台湾的镜像了
    再探OAuth2
    【转】Android世界的Swift
    内存只有4G的MBP要怎么破
  • 原文地址:https://www.cnblogs.com/czy960731/p/10824366.html
Copyright © 2020-2023  润新知