移动端适配方案

移动端适配

    • (一)移动端适配方案
    • (二)响应式设计相关的几个概念
    • (三)获取窗口大小的api
    • (四)横屏适配问题
    • (五)移动端调试

(一)移动端适配方案

1、缩放

动态设置标签

(function adapt(){
	const cueWidth = window.screen.width;
	const targetWidth = 750;
	const scale = curWidth / targetWidth;
	const meta = document.createElement('meta');
	meta.name = 'viewport';
	meta.content = `initial-scale=${scale},minimum-scale=${scale}.maximum-scale=${scale}`;
	document.head.appendChild(meta);
})()

2、flexible rem布局方案
通过计算不同的手机尺寸设置根节点的font-size,

(function flexible (window, document) {
  var docEl = document.documentElement
  var dpr = window.devicePixelRatio || 1

  // 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()
    }
  })

  // 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')
    }
    docEl.removeChild(fakeBody)
  }
}(window, document))

rem 是相对于html节点的font-size来计算的,代码中将HTML的font-size设置为布局视口的 1/10 docEl.clientWidth / 10

3、vh、vw方案

vw(Viewport's width):1vw等于视觉视口的1%
vh(Viewport's height) :1vh 为视觉视口高度的1%
vmin : vw 和 vh 中的较小值
vmax : 选取 vw 和 vh 中的较大值
PostCSS的 postcss-px-to-viewport 插件帮我们完成px到vw的转换。写代码时,我们只需要根据UI给的设计图写px单位即可。
缺陷:px转换成vw不一定能完全整除,因此有一定的像素差。
比如当容器使用vw,margin采用px时,很容易造成整体宽度超过100vw,从而影响布局效果。当然也是可以避免的,例如使用padding代替margin,结合calc()函数使用等等

(二)响应式设计相关的几个概念

在开发过程中,会遇到很多概念,比如:像素、分辨率、PPI、DPI、DP、DIP、DPR、视口等等,这些概念对应的意义分别是什么呢?

1、像素(Pixe)
像素即一个个的小方块,具有特定的位置和颜色。一个显示屏的成像原理是通过一系列的小点排列成的一个矩形,每一个小点叫做一个物理像素。而屏幕分辨率就是指一个屏幕具体由多少个像素点组成的。
每英寸像素取值(Pixel per inch, PPI)的意思就是每一英寸内的物理像素数量,屏幕的PPI越高,则说明同一大小的屏幕上能显示的物理像素越多,能给图像提供更多的细节,拟真度就越高。
常说的图片分辨率即指图片内含有的物理像素数。
DPI表示每英寸包含的点数,DPI常用于描述打印机的点数,打印机的DPI越高,打印的图像越精细。

2、独立设备像素

随着科技的发展,手机的分辨率逐渐提升,因此我们需要用同一单位告诉不同分辨率的手机,在界面上个显示元素的大小是多少,即设备独立像素即DIP或DP,
设备像素比(DPR)即物理像素与设备独立像素的比值。可以使用window.devicePixelRatio来获取dpr,CSS中可以使用@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){ }区分dpr。

开发过程中,我们使用的px作为长度单位,px指css像素,在页面未缩放,一个CSS像素等于一个物理像素,当用户对浏览器缩放后,css像素会被缩放,此时页面的缩放系数 = CSS像素 / 设备独立像素

3、视口
视口(viewport)代表当前可见的计算机图形区域,在CSS里定义的是元素的包含块。视口包含有三种:布局视口,视觉视口和理想视口。

布局视口(layout viewport):当以百分比计算一个元素的大小时,计算值基于这个元素的包含块计算来的,当元素为顶级元素时,基于布局视口计算的。所以布局视口是网页布局的基准窗口,在pc上,布局视口等于当前浏览器的窗口大小,在移动端,布局视口被赋予一个默认值,大部分为980px,这保证PC的网页可以在手机浏览器上呈现,但是非常小,用户可以手动对网页进行放大。使用document.documentElement.clientWidth / clientHeight来获取布局视口大小。
移动端适配方案_第1张图片

视觉视口(visual viewport):用户看到的真实区域。当用户对浏览器进行缩放时,不会改变布局视口的大小,所以页面布局是不变的,但是缩放会改变视觉视口的大小。通过调用window.innerWidth / innerHeight来获取视觉视口大小。

理想视口(ideal viewport):网站页面在移动端展示的理想大小页面的缩放系数 = 理想视口宽度 / 视觉视口宽度

4、viewport
可以设置元素的viewport,来设置视口,缩放等。viewport的设置:

value 描述
width 以pixels(像素)为单位, 定义布局视口的宽度。
height 以pixels(像素)为单位, 定义布局视口的高度。
initial-scale 定义页面初始缩放比率。。
minimum-scale 定义缩放的最小值;必须小于或等于maximum-scale的值。
maximum-scale 定义缩放的最大值;必须大于或等于minimum-scale的值。
user-scalable 如果设置为 no,用户将不能放大或缩小网页。默认值为 yes。

(三)获取窗口大小的api

  • 获取浏览器视口高度(包括垂直滚动条):window.innerHeight;
  • 获取浏览器窗口外部的高度:window.outerHeight;
    窗口可视区域宽度:document.documentElement.clientWidth ||document.body.clientWidth;
  • 窗口可视区域高度:
    document.documentElement.clientHeight ||document.body.clientHeight;
  • 窗口可视区域宽度+边线和滚动条: document.body.offsetWidth ;
  • 窗口可视区域高度+边线和滚动条: document.body.offsetHeight ;
  • 实际内容的宽度: document.body.scrollWidth;
  • 实际内容的高度: document.body.scrollHeight;
  • 滚动条下拉被卷起来的距离:
    document.documentElement.scrollTop || window.pageYOffset ||document.body.scrollTop;
  • 滚动条侧拉被卷起来的距离:
    document.body.scrollLeft || document.documentElement.scrollLeft ;
  • 网页正文部分上:window.screenTop;
  • 网页正文部分左:window.screenLeft;
  • 元素的宽度:obj.offsetWidth;
  • 元素的高度:obj.offsetHeight;
  • 相对于父元素的上位移:obj.offsetTop;(在元素的包含元素不含滚动条的情况下)
  • 相对于父元素的左位移:obj.offsetLeft;(在元素的包含元素不含滚动条的情况下)

(四)横屏适配问题

js检测横屏

window.addEventListener("resize", ()=>{
    if (window.orientation === 180 || window.orientation === 0) { 
      // 竖屏  正常方向或屏幕旋转180度
    };
    if (window.orientation === 90 || window.orientation === -90 ){ 
       //横屏  屏幕顺时钟旋转90度或屏幕逆时针旋转90度
    }  
}); 

window.orientation 屏幕旋转方向

CSS检测横屏

@media screen and (orientation: portrait) {
  /*竖屏*/
} 
@media screen and (orientation: landscape) {
  /*横屏*/
}

(五)移动端调试

1、VConsole

下载安装:npm install vconsole
引入使用:

const VConsole = require('vconsole');
new VConsole();

2、spy-debugger

控制台安装 npx spy-debugger -p 8888
手机和pc保持在同一网络下,手动设置代理,ip设置为pc的ip地址,端口为spy-debugger启动的端口,
使用手机访问要访问的页面
抓包页面

移动端适配方案_第2张图片

你可能感兴趣的:(项目实践记录)