zoukankan      html  css  js  c++  java
  • 移动端开发

    对于移动端开发而言,为了做到页面高清的效果,视觉稿的规范往往会遵循以下两点:

    1)选取一款手机的屏幕宽高作为基准(比如 iphone6的375×667)。

    2)对于高清屏幕,为了达到高清效果,视觉稿的画布大小会是基准的2倍(对iphone6而言:原先的375×667,就会变成750×1334)。

    问题1:对于dpr=2的手机,为什么画布大小×2,就可以解决高清问题?

    首先,我们要先了解一下 dpr 是什么?

    • 设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:
    设备像素比 = 物理像素 / 设备独立像素    // 在某一方向上,x方向或者y方向
    • 一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。
    • 设备独立像素,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。  

     总而言之,就是不同的设备(不同的系统),他们有不同的dpr,这些设备在拿到前端写好的页面(即css像素布局)之后,会根据dpr占用不同数量的物理像素。但是,它们最终显示(肉眼识别)的大小是一样的。

     盗用一张图:

    那这和一开始的问题:对于dpr=2的手机,为什么画布大小×2,就可以解决高清问题? 有什么关系? 再盗用一张图~

    这样子就非常清晰了,对于dpr=2的高清(retina)屏幕而言,1个位图像素对应于4个物理像素,由于单个位图像素不可以再进一步分割,所以只能就近取色,从而导致图片模糊(注意上述的几个颜色值)。

    因为这样,我们干脆就使用2倍大的图片,比如:200*300的图片,在高清屏上,就使用400*600的图片,但是显示的大小仍然设置为200*300,这样子的话,一个物理像素仍然是显示一个位图像素,完美。

    问题2:类似于下面的布局,在使用最少标签的情况下,如何适配所有移动端屏幕?并且保存一定的宽高比,不失真。

    1. 使用百分比 % 进行布局

    假如你使用%对该块进行布局,很快,你就会觉得非常的‘苦逼’,由于每一块有margin值,而margin的百分比你很难去计算得到,并且,你可能需要用到各种不同的媒体查询 

    @media(max-320px){
        div{margin-right: 1%;}
    }

    每一个屏幕你都可能需要微调,并且,当以后需要修改样式的时候,你又需要每个@media都重新走一遍,想想就后怕

    2.使用 rem 布局

    正所谓,原理大家都懂,rem是根据根元素html的font-size的大小,直接看例子吧~

    1 html{font-size: 16px;}
    2 body{
    3      font-size: 0.5rem;  /*16px * 0.5 = 8px;*/
    4 }

    基于rem的原理,我们要做的就是:  针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小(基准值)。

    回到题目上,那怎么使用rem去实现该布局?并且,在设置rem的过程都非常愉快,不需要经过各种恼人的计算?

    根据当前viewport的尺寸来改变html的字体大小,一般分为媒体查询和js动态计算两种。

    前者必须针对市面上较为主流的分辨率作媒体查询的区间分界点,缺点是只有设置为分界点的尺寸完美缩放,分界点之间的尺寸会出现断层。

    js根据屏幕尺寸去动态计算则能令所有尺寸完美缩放,缺点则是要在页面头部插入一小段js代码。

    根据这2个的优缺点,在日常开发中,h5运营页面经常使用js动态计算的方法,而平常的页面(购物,网页)则使用媒体查询的方法。

    一般在开发中,我们会选择一个屏幕作为基准(比如 iphone6 的 375) ,在该屏幕下,font-size基准设置为20px

    先上一个非常巧妙,极大地提高了开发效率但是原理却很简单的方法。

    $rem_grid: 20 !default;  //使用 rem(10)即在375屏幕中代表10px
    @function rem($val){
        $rem : $val / $rem_grid;   //由于rem是先乘以font-size得出px,所以这里先把rem()传进来的数除以20,最后乘以html的20,其实就是参数的本来值
        @if $rem == 0 {
            @return #{$rem} ;
        }@else{
            @return $rem / ($rem * 0 + 1) * 1rem; // 带不带px单位都支持
        }
    }

    好了,方便计算的做了,接下来是媒体查询,覆盖常见机型?

    原理:根据设备的宽度(与基准设备宽度375的比值)进行缩放。废话不多说,直接上代码

    @mixin query( $limit ) {
        @media screen and ( min- $limit) {  //媒体查询
            & {
                @content;
            }
        }
    }
    @mixin _mod_cross( $width, 375 ) {
        @include query( $width * 1px ) {
            font-size:  $width / 375 * 20 * 1px;  //这里是关键
        }
    }
    @include _mod_cross(320, 375);   //iPhone5
    复制代码

    按照上面实现之后,当然,你要@include _mod_cross 常见的机型,这样之后,你就终于终于可以,只在iphone6下,愉快地用rem()进行布局了,无须每一个屏幕都去做适配,也无须每一次都多一步计算,大大提高开发效率。

    写完媒体查询的方法,再上一份用js动态计算的代码:

    原理是一样的,只是使用 document.documentElement.clientWidth 获取更加精确的设备宽度,再对html的font-size进行设置。

    <script type="text/javascript">
        !function(){
          var maxWidth=750;
          document.write('<style id="o2HtmlFontSize"></style>');
          var o2_resize=function(){
              var cw,ch;
              if(document&&document.documentElement){
                  cw=document.documentElement.clientWidth,ch=document.documentElement.clientHeight;
              }
              if(!cw||!ch){
                  if(window.localStorage["o2-cw"]&&window.localStorage["o2-ch"]){
                      cw=parseInt(window.localStorage["o2-cw"]),ch=parseInt(window.localStorage["o2-ch"]);
                  }else{
                      chk_cw();//定时检查
                      return ;//出错了
                  }
              }
              var zoom=maxWidth&&maxWidth<cw?maxWidth/375:cw/375,zoomY=ch/603;//由ip6 weChat
              window.localStorage["o2-cw"]=cw,window.localStorage["o2-ch"]=ch;
              //zoom=Math.min(zoom,zoomY);//保证ip6 wechat的显示比率
              window.zoom=window.o2Zoom=zoom;
              document.getElementById("o2HtmlFontSize").innerHTML='html{font-size:'+(zoom*20)+'px;}.o2-zoom,.zoom{zoom:'+(zoom/2)+';}.o2-scale{-webkit-transform: scale('+zoom/2+'); transform: scale('+zoom/2+');} .sq_sns_pic_item,.sq_sns_picmod_erea_img{-webkit-transform-origin: 0 0;transform-origin: 0 0;-webkit-transform: scale('+zoom/2+');transform: scale('+zoom/2+');}';
          },
          siv,
          chk_cw=function(){
              if(siv)return ;//已经存在
              siv=setInterval(function(){
                  //定时检查
                  document&&document.documentElement&&document.documentElement.clientWidth&&document.documentElement.clientHeight&&(o2_resize(),clearInterval(siv),siv=undefined);
              },100);
          };
          o2_resize();//立即初始化
          window.addEventListener("resize",o2_resize);
      }();
      </script>

    rem的应用场景:

    由于 rem 布局是相对于视口宽度,因此任何需要根据屏幕大小进行变化的元素(width、height、position 等)都可以用 rem 单位。

    但 rem 也有它的缺点——不精细,其实这涉及到了浏览器渲染引擎的处理。因此,对于需要精细处理的地方(如通过 CSS 实现的 icon),可以用 px 等绝对单位,然后再通过 transform: scale() 方法等比缩放。

  • 相关阅读:
    数组乘积更新
    win向linux传文件
    遇到autoreconf: not found
    python thread
    aptitude
    virtualbox安装ubuntu出现“The system is running in low-graphics mode”
    webform用户控件
    LinQ to SQL
    表单验证
    文件上传
  • 原文地址:https://www.cnblogs.com/wangqiniqn/p/6280044.html
Copyright © 2011-2022 走看看