移动端开发—适配

244 阅读3分钟

看了那么多篇文章,总算开窍了。带着问题去学习会让我们记忆深刻一些:

1、rem

rem的定义很简单就是 HTML 元素定义的 font-size 的值。如果 html 的 font-size: 7.2px; 那么 1rem = 7.2px。那么采用rem单位,比较宽的设备 html 的 font-size 设置大一些,对应的元素也就宽一些,大一些;font-size小的话,对应元素就小一些。

至于rem和px直接怎么转换,个人喜好了。我看网上有些直接除以10的,有些是根据设计稿尺寸,换算方便计算的。例如,设计稿宽度是 750px, 我们可以设置 1rem = 40px。为什么是40,因为 40除起来是整数。

(function () {   
  'use strict';    
  setRemUnit();    
  window.addEventListener('resize', setRemUnit);   
  function setRemUnit() {        
    var domEI = document.documentElement;       
    var ratio = 18.75;        
    var viewWidth = domEI.getBoundingClientRect().width || window.innerWidth;       
    domEI.style.fontSize = viewWidth / ratio + 'px';    
  }
})();

如果我们的设计稿是 720px,但是还是想用 1rem = 40px, 怎么计算呢?很简单:

(function () {   
  'use strict';    
  setRemUnit();    
  window.addEventListener('resize', setRemUnit);   
  function setRemUnit() {        
    var domEI = document.documentElement;       
    var ratio = 18;  //    720/40      
    var viewWidth = domEI.getBoundingClientRect().width || window.innerWidth;       
    domEI.style.fontSize = viewWidth / ratio + 'px';    
  }
})();

2、viewport

  • PC 端 viewport 大小等于浏览器窗口的大小。
  • 在移动设备上 viewport 不再受限于浏览器的窗口,而是允许开发人员自由设置 viewport的大小,通常浏览器会设置一个默认大小的viewport,为了能够正常显示那些转为PC设计的网页,一般这个值的大小会大于屏幕的尺寸(造成滚动条的出现,这样可以看全整个PC端页面)。

三个 viewport 理论

  • visual viewport (视觉上的 viewport,可视区域的大小)

  • layout viewport  网页布局的 viewport;也就是 meta 标签中 设置的 viewport 

    // 可以通过下面方式获取
    document.documentElement.clientWidth

  • ideal viewport 意义在于,无论在何种分辨率的屏幕下,那些针对ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。其大小是不能被改变的。

    // 可以通过下面方式获取 window.screen.width

通过上面的两个知识点,那么如果我们的移动端页面不设置 meta 的 viewport 大小会导致页面出现横向滚动条。为什么呢?移动端浏览器厂商给了 网页viewport (也就是 layout viewport)默认值,如苹果的是 980,但是 visual viewport 没有那么大,只有 375。所以导致了横向滚动条的出现。

综上,我们在开发移动端页面的时候,提前设置好页面的 viewport 为移动端设备的宽度,以保证视图的完备。

<meta name="viewport" content="width=device-width,initial-scale=1.0,
maximum-scale=1.0,user-scalable=0">

3、DPR(1px的问题)

rem可以解决不同分辨率元素大小的问题;但是对于1px的边框显示无法解决。对于某个元素,设置边框:border: 1px solid black; 在不同DPR上面显示的是不一样的。

www.jianshu.com/p/9340fb4e9… 文章中关于物理像素、设备独立像素、设备像素比描述的很清楚了。

现象就是 1px的边框在 2倍或3倍屏上显示的比较粗。为了最求产品的完美,可以利用 viewport对页面根据 dpr 进行相应的缩放。

var domEI = document.documentElement,    
viewportEI = document.querySelector('meta[name="viewport"]'),    
dpr = window.devicePixelRatio || 1,    
maxWidth = 540,    
minWidth = 320;dpr = dpr >= 3 ? 3: (dpr >=2 ? 2 : 1);
//自定义属性
domEI.setAttribute('data-dpr', dpr);
domEI.setAttribute('maxWidth', maxWidth);
domEI.setAttribute('minWidth', minWidth);
var scale = 1/dpr,    
content = 'width=device-width, initial-scale=' + scale + ', maximum-scale='+        scale+', minimum-scale='+scale+', user-scalable=no';
if(viewportEI){    
    viewportEI.setAttribute('content', content);} 
else {    
    viewportEI = document.createElement('meta');    
    viewportEI.setAttribute('name', 'viewport');    
    viewportEI.setAttribute('content', content);    
    document.appendChild(viewportEI);
}

问题:为什么1px被缩放了0.5倍或者0.33倍,元素大小不会受影响吗?

是的,不会。因为元素大小是用的rem单位,也就是当视口的宽度变小,rem也会变小。即:元素相对于视口的相对大小并不会变化的。

juejin.cn/post/684490…

问题:元素相对于页面视口的大小不变,但是字体大小(px)受影响,怎么办?

因为字体一般采用px,那么对应也要对字体的元素进行处理,如下:

//CSS
[data-dpr="2"] body,
[data-dpr="2"] a,
[data-dpr="2"] 
input{    
    font-size: 24px;
}
[data-dpr="3"] body,
[data-dpr="3"] a,
[data-dpr="3"] input
{    
    font-size: 36px;
}

// html data-dpr="2"是根据window.devicePixelRatio动态变化的
<html lang="zn-Ch" data-dpr="2">
...
</html>