关于移动端适配你了解多少? | 社区征文

社区征文

背景介绍

我们公司的APP是通过安卓写的壳子,里面嵌套了前端开发的Vue页面或者H5页面。H5或Vue再去调用android或者IOS原生写的的方法。之前我接手的部分业务,为保证功能完整性,入口也需要使用H5实现,当时遇到了一些问题,其中包括布局适配问题。 本篇文章共2226字,阅读大概需要8分钟

核心:适配问题

说到布局,首先要提出来的就是viewport,哪viewport是什么?我们为什么需要使用它?

一、viewport

基本概念viewport指视口,浏览器上(或者是手机app的webview)的显示网页的区域。

PC端的视口是浏览器窗口区域,而移动端的则存在三个不同的视口以及meta标签:

  • layout viewport:布局视口
  • visual viewport:视觉视口(浏览器可视区域)
  • ideal viewport:理想视口
  • Meta viewport:meta标签

接下来分别介绍一下这四个概念:

layout viewport:布局视口

在PC端的网页的layout viewport即浏览器页面显示的整个区域,也可以理解成网页的绘制区域。而在移动端由于其屏幕较小,无法全部显示PC端页面的全部内容,所以默认情况下,移动端会指定一个大于其浏览器显示区域layout viewport。

visual viewport:视觉视口(浏览器可视区域)

这里我们使用两幅图来进行区分一下:

layout viewport:

1532326331-2895-201407.png

visual viewport:

1532326332-9414-201407.png

ideal viewport:理想视口

理想视口,即页面绘制区域可以完美适配设备宽度的视口大小,不需要出现滚动条即可正常查看网站的所有内容,且文字图片清晰。这也是我们为什么需要使用viewport的原因。

kkk.jpg

Meta viewport

<meta> 元素表示那些不能由其它HTML元相关元素之一表示的任何元数据信息,它可以告诉浏览器如何解析页面。

我们可以借助<meta>元素的viewport来帮助我们设置视口、缩放等,从而让移动端得到更好的展示效果

<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">

viewport属性含义:

Value可能值描述
width正整数或device-widthpixels(像素)为单位, 定义布局视口的宽度。
height正整数或device-heightpixels(像素)为单位, 定义布局视口的高度。
initial-scale0.0 - 10.0定义页面初始缩放比率。
minimum-scale0.0 - 10.0定义缩放的最小值;必须小于或等于maximum-scale的值。
maximum-scale0.0 - 10.0定义缩放的最大值;必须大于或等于minimum-scale的值。
user-scalable一个布尔值(yes或者no如果设置为 no,用户将不能放大或缩小网页。默认值为 yes。

二、移动适配解决方案

移动布局分式有很多种,这里简单介绍3种布局方式:

 flex弹性布局(最常用)

介绍:采用 Flex 布局的元素,称为 Flex Container。它的所有子元素自动成为容器成员,称为Flex Item。最大的作用就是:通过给父亲添加flex属性,从来控制内部项目的位置及排序方式。

优点方面:

  • 使用方便,根据flex规则很容易达到一定的布局效果

缺点方面:

  • 浏览器兼容性比较差,只能兼容ie9及以上
 流式布局(百分比布局)

介绍:页面元素的宽度会根据屏幕分辨率自动进行适配。这种布局可以保证当你的屏幕分辨率发生改变也不会发送混乱,会一直保持适配。

优点方面:

  • 宽度自适应,在不同的分辨率下都能达到适配

缺点方面:

  • 百分比的值不好计算
  • 需要确定父级的大小,因为要根据父级的大小进行计算
  • 各个属性中如果使用百分比,相对父元素的属性并不是唯一的
  • 高度不好设置,一般需要固定高度
 css3的媒体查询
@media screen and (max-width: 320px){
    ....适配小屏幕的css样式
}
@media screen and (max-width: 375px){
     ....适配普通屏幕的css样式
}
@media screen and (max-width: 414px){
    ....适配大屏幕的css样式
}

优点方面

  • 方法简单,只需修改css文件
  • 调整屏幕宽度时不用刷新页面就可以响应页面布局

缺点方面

  • 代码量大,不方便维护
  • 不能够完全适配所有的屏幕尺寸,需要编写多套css样式

思考(1px问题):

物理像素:

指的是设备屏幕上的像素点个数,比如苹果6是屏幕尺寸为4.7英寸,分辨率为1334x750像素,那么水平方向上有750个像素点,竖直方向上有1334个像素点

CSS像素:

在我们去写CSS时,我们用到最多的单位是px,指的就是CSS像素,当页面缩放比例为100%时,一个CSS像素等于一个设备独立像素。

但是CSS像素是很容易被改变的,当用户对浏览器进行了放大,CSS像素会被放大,这时一个CSS像素会跨越更多的物理像素。

页面的缩放系数 = CSS像素 / 设备独立像素

在我们了解了以上之后,这里我抛出一个问题,基本上前端开发都会遇到的问题 图片模糊 ,当时刚参加工作时,遇到了这个问题,然后查阅了资料之后才算是搞清楚原理。

图片模糊产生原因

我们平时使用的图片大多数都是PNG、JPG之类的,学过PS的人都知道,这些图都是通过一个个像素点构成的,每一个像素都有具体的位值和颜色值(像素值),在开发中,位图的每一个像素应该去对应上设备的物理像素,对应上之后,才可以达到最佳效果,当然就不会产生图片迷糊这个问题。而在设备像素比 > 1的屏幕上,1个位图像素对应于多个个物理像素,由于单个位图像素不可以再进一步分割,所以只能就近取色,导致图片看起来比较模糊。

图片模糊解决方案

解决方案其实也很简单。我们只要让一个屏幕像素来渲染一个图片像素,所以,针对不同设备像素比的屏幕,我们需要展示不同分辨率的图片。

如:在设备像素比=2的屏幕上展示两倍图(@2x),在设备像素比=3的屏幕上展示三倍图(@3x)

diei.png

开发中遇到的布局问题:

场景一: APP原生功能页中,预留空白窗口,然后窗口中加载H5入口资源。
解决方案:

H5在组件加载完毕后,offsetHeight 获取当前组件高度,与APP通信告知H5入口组件的高度,APP拿到此高度后,设定适宜的窗口大小以容纳内嵌的H5入口组件

预知条件:H5调用方法时Android与iOS不同

H5 调用

Androidwindow.app.funName(data)

H5 调用 iOS: window.webkit.messageHandlers.app.postMessage({cmd: 'funName',data:data});

/**
 * updateViewSize 为H5调用与APP协商的方法名
 * entranceHeight 为H5的入口组件高度
 */ 
<template>
    <div class="entrance" ref="appHeight"></div>
</template>
<script>
        // 当前组件的高度
        this.entranceHeight= this.$refs.appHeight.offsetHeight;
        //通知APP,当前组件的高度
        this.isAndroid ? window.app.updateViewSize(this.entranceHeight) : window.webkit.messageHandlers.app.postMessage({
            cmd: 'updateViewSize',
            data: this.entranceHeight});
         });
</script>
场景二:当组件内容可变或动态获取,造成组件高度首次获取不准确
  • 背景: 文案为后端返回,且有时切换语言造成换行,导致高度变化
解决方案:
  • H5与APP通信告知高度的时机,添加在mounted即可
  • 为了准确,最好watch服务端返回的文案数据,数据变化则等DOM更新完就通信
  watch: {
         /**
          * 监听数据变化,DOM更新后及时通知APP最新高度,调整窗口
          * 接口返回数据后,文案可能换行导致窗口高度发生改变
          */
         someData() {
             this.$nextTick(()=>{
             // 当前组件的高度
             this.entranceHeight= this.$refs.appHeight.offsetHeight;
             //通知APP,当前组件的高度
             this.isAndroid ? window.app.updateViewSize(this.entranceHeight) : window.webkit.messageHandlers.app.postMessage({
             cmd: 'updateViewSize',
             data: this.entranceHeight});
          });
         }
     },

结尾

以上就是对布局适配的理解和认识,总结的不足之处和理解不对的地方,欢迎指出讨论。感谢阅读!

542
7
3
3
关于作者
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论