关于移动端页面适配性的摸索

  第一次写这种技术博客,感觉自己语言组织地很混乱,排版也不够清晰,不知道到底表达出来我的意思没有...

  看了这篇文章的朋友,请多多包涵,有问题的地方也烦请指出。感谢!

 

  对于刚开始接触前端的程序猿来说,写页面的适配性估计是最头痛的一件事。

  现在市面上有众多的手机种类,也就存在众多不同的手机分辨率。所以一个页面要想适配所有手机的分辨率,在我当时看来,真的是一件很难的事情。当时公司为了这个,专门买了几款比较经典的手机用来作为测试机,专门测试页面的适配性。但是即使这样,也不可能照顾得到市面上的所有手机。

  我们大概是这样一路走过来的:

 

  一、入门方法

  写页面的适配性,最入门的方法应该就是媒体查询了。针对不同分辨率的手机,专门写一条媒体查询去针对性的调整某些css样式。这种方法很容易就会产生出大量的媒体查询代码块,使得页面的可读性变差,并且容量也大了很多。

@media (min-width: 320px) and (max-height: 416px) {
  /*iphone4*/
  ...
}

@media(max-width: 320px) and (min-height: 504px) {
  /*iphone5*/
  ...
}

@media (min-width: 375px) and (max-height: 603px) {
  /*iPhone 6*/
  ...
}

@media (min-width: 414px) and (max-height: 672px) {
  /*iPhone 6p*/
  ...
}

@media (min-width: 360px) and (max-height: 519px) {
  /*Android*/
  ...
}

 

  二、进阶方法

  上面的办法我们一直用了很长时间,那段时间的前端效率确实低到一种境界了。直到后来我对rem这个css单位的深入研究之后,才开始有了转机。

  什么是rem单位。简单的说,rem就是一种相对长度单位,它是相对于页面根元素(html)的font-size来计算出的长度单位。举个栗子吧:

<html>
  <head>
    <style>
      div {
        width: 1rem;
        height: 1rem;
      }
    </style>
  </head>
  <body>
    <div></div>
  </body>
</html>

  

   在这个例子中,div的长宽会被浏览器设置为16px。

 

 

  好了,那么原理是什么呢?因为rem是以根元素(html)的font-size属性为基础计算出来的长度,那么在这个例子中,html元素的font-size我们并没有设置,所以默认为16px,然后因为width和height都设置为1rem,所以最终长度为 16(px) * 1(rem) = 16(px)。

  到这里,我们就有了解决适配性的思路:只要让html的font-size属性跟随页面宽度进行成比例变化,那么元素中设置的rem长度换算出来的px长度可以跟随页面宽度也成比例变化。公式为:f(font-size) = a(比例) * W(页面宽度),length = f * rem。

  上面的描述比较抽象,还是来举个栗子吧:

  假设前端设计图的宽度是640px,其中有一个长度为200px的输入框。我们设定当页面宽度为640px时,html的font-size属性值为40px,即上述f=aW公式中a的值为f / W = 0.0625。那么这个输入框的长度用rem表示就应该是rem = length / f = length / aW = 200(px) / (0.0625 * 640(px)) = 5rem

  如果页面宽度变成了320px,则我们让html的font-size属性也跟随变化为f = aW = 0.0625 * 320 = 20px,对于这个长度为5rem的输入框来说,实际计算出来的长度为20(px) * 5(rem) = 100(px)。这样就可以看到,设置为固定rem长度的输入框,在不同页面宽度下,实现了等比例缩放的效果。

  上个效果图吧。

  在实际项目中,为了让html的font-size属性能够跟随页面宽度变化,我找了一个js来达到这个效果。

 

   自动计算font-size的js代码:

(function (doc, win) {
  var docEl = doc.documentElement,
  resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
  recalc = function () {
    var clientWidth = docEl.clientWidth;
    if (!clientWidth) return;
    docEl.style.fontSize = 20 * (clientWidth / 320) + 'px';
  };

  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
  doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

  

  三、高阶方法

  在采用了上面这种方法之后,项目的大部分页面都不再存在适配性的问题了。但是在个别比较特殊的页面上,由于px长度只能是整数,就会刚好因为取整时产生的1px的差距,导致整个页面的显示出现错位的现象。所以我个人认为应该还有一种高阶的方法,这种方法需要UI同事的配合,在设计页面上,尽量预先划分好各个板块的功能,在某些内容会变动、可能需要弹性伸缩的地方预留空间;而在另外一些必须按原比例显示的地方,就不要设计有可能变动的内容。同时也要求前端同事在分析页面的布局时,尽量能针对不同的内容来选择不同的布局方式。

  

 

posted @ 2017-06-12 14:32  蛋先生  阅读(375)  评论(0编辑  收藏  举报