前端知识体系7.移动端/多平台
本文目录:
- 1.说一下viewport的常见属性
- 2.说一下物理像素、逻辑像素、DPR、1px边框问题
- 3.移动端适配解决方案
- 4.使用 rem 布局的优缺点
- 5.jsBridge是什么?
- 6.移动端事件有哪些?
- 7.移动端实现滑动一个dom结构
- 8.PWA是什么?,讲下核心点
- 9.Weex?
1.说一下viewport的常见属性
为了方便理解,以iphone6为例
●屏幕物理分辨率:7501334
●屏幕逻辑分辨率:375667 (screen.width/height)
●设备像素比(dpr):2 (window.devicePixelRatio)
width
<meta name="viewport" content="width=1000" />
●document.documentElement.clientWidth 输出 1000
●div 宽度 1000px 时,横向刚好铺满屏幕,超过出现横向滚动条
<meta name="viewport" content="width=device-width" />
●效果等同于 width=375
●document.documentElement.clientWidth 输出 375
●div 宽度 375px 时,横向刚好铺满屏幕,超过出现横向滚动条
**initial-scal **
<meta name="viewport" content="initial-scale=1" />
●效果等同于 width=device-width
<meta name="viewport" content="initial-scale=2" />
●document.documentElement.clientWidth 输出 188 (375/2)
●div 宽度 188px 时,横向刚好铺满屏幕,超过出现横向滚动条
●scale 倍数越小,视口越大
maximum-scale / minimum-scale
<meta
name="viewport"
content="initial-scale=2,minimum-scale=1,maximum-scale=3"
/>
允许用户进行缩放的最小倍数和最大倍数
user-scalable
<meta name="viewport" content="initial-scale=1,user-scalable=no" />
是否允许用户进行缩放
2.说一下物理像素、逻辑像素、DPR、1px边框问题
设备像素 = 物理像素
CSS 像素 = 逻辑像素
设备像素比 device pixel ratio 简称 dpr,即物理像素和设备独立像素的比值。
详细内容见文集《移动端/多平台》=>《物理像素、逻辑像素、1px边框问题》
1px边框问题:
出现的原因:
在retina屏的手机上, dpr为2或3,css里写的1px宽度映射到物理像素上就有2px或3px那么宽,所以会导致边框看上去比较粗。
解决办法:
transform: scale(0.5) 方案
div {
height:1px;
background:#000;
-webkit-transform: scaleY(0.5);
-webkit-transform-origin:00;
overflow: hidden;
}
css 根据设备像素比媒体查询后的解决方案
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
3.移动端适配解决方案
1.目前主流的rem布局方式,但是这种方式注定是一个过渡品,因为用户使用更大的屏幕,是想看到更多的内容,而不是更大的字。
2.vw,vh布局
vh、vw 方案即将视觉视口宽度 window.innerWidth 和视觉视口高度 window.innerHeight 等分为 100 份。
vh 和 vw 方案和 rem 类似也是相当麻烦需要做单位转化,而且 px 转换成 vw 不一定能完全整除,因此有一定的像素差。
不过在工程化的今天,webpack 解析 css 的时候用 postcss-loader 有个 postcss-px-to-viewport 能自动实现 px 到 vw 的转化
{
loader: 'postcss-loader',
options: {
plugins: ()=>[
require('autoprefixer')({
browsers: ['last 5 versions']
}),
require('postcss-px-to-viewport')({
viewportWidth: 375, //视口宽度(数字)
viewportHeight: 1334, //视口高度(数字)
unitPrecision: 3, //设置的保留小数位数(数字)
viewportUnit: 'vw', //设置要转换的单位(字符串)
selectorBlackList: ['.ignore', '.hairlines'], //不需要进行转换的类名(数组)
minPixelValue: 1, //设置要替换的最小像素值(数字)
mediaQuery: false//允许在媒体查询中转换px(true/false)
})
]
}
3.flex布局
4.传统的px布局并不一定会被淘汰,尽管开发成本高,但是能更符合用户的需求,可以考虑使用
px 为主,vx 和 vxxx(vw/vh/vmax/vmin)为辅,搭配一些 flex
5.在跨设备类型的时候(pc <-> 手机 <-> 平板)使用媒体查询
- 在跨设备类型如果交互差异太大的情况,考虑分开项目开发
4.使用 rem 布局的优缺点
优点
等比缩放,百分百还原,特别适合纯移动端app布局使用。
缺点
1.计算量大,可以通过插件解决
2.字体不适合用rem,因为字体的大小和字体宽度,并不成线性关系,可以给bldy标签赋值一个默认的字体大小px,然后需要设置字体大小的元素用em,不定义的话则默认继承。
如果既想用em,又想使用响应式,则需要用到媒体查询
@media screen and (min-width: 320px) {
body {font-size: 16px}
}
@media screen and (min-width: 481px) and (max-width:640px) {
body {font-size: 18px}
}
@media screen and (min-width: 641px) {
body {font-size: 20px}
}
p {font-size: 1.2em}
p a {font-size: 1.2em}
3.兼容性问题,IE不支持rem
4.灵活性差,如果全部使用rem进行布局的话,有的大屏用户想看到更多的字,有的想看到更大字或者图标,而rem会扼杀这种选择。
5.jsBridge是什么?
jsBridge主要是给 JavaScript 提供调用 Native 功能的接口,让混合开发中的前端部分可以方便地使用 Native 的功能(例如:地址位置、摄像头)。
而且 JSBridge 的功能不止调用 Native 功能这么简单宽泛。实际上,JSBridge 就像其名称中的Bridge的意义一样,是 Native 和非 Native 之间的桥梁,它的核心是构建 Native 和非 Native 间消息通信的通道,而且这个通信的通道是双向的。
1.JS 向 Native 发送消息: 调用相关功能、通知 Native 当前 JS 的相关状态等。
2.Native 向 JS 发送消息: 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。
6.移动端事件有哪些?
1. click点击事件
移动端有300ms延迟,解决方法是使用fastclick插件或者禁止屏幕缩放。
2.touch类触摸事件
触摸事件,有touchstart touchmove touchend touchcancel 四种之分
touchstart:手指触摸到屏幕会触发
touchmove:当手指在屏幕上移动时,会触发
touchend:当手指离开屏幕时,会触发
touchcancel:可由系统进行的触发,比如手指触摸屏幕的时候,突然alert了一下,或者系统中其他打断了touch的行为,则可以触发该事件
touch事件对应的基本属性
screenX:触摸点相对于屏幕左边缘的 x 坐标。
screenY:触摸点相对于屏幕上边缘的 y 坐标。
clientX:触摸点相对于浏览器的 viewport左边缘的 x 坐标。不会包括左边的滚动距离。
clientY:触摸点相对于浏览器的 viewport上边缘的 y 坐标。不会包括上边的滚动距离。
pageX:触摸点相对于 document的左边缘的 x 坐标。 与 clientX 不同的是,他包括左边滚动的距离,如果有的话。
pageY:触摸点相对于 document的左边缘的 y 坐标。 与 clientY 不同的是,他包括上边滚动的距离,如果有的话。
target:总是表示 手指最开始放在触摸设备上的触发点所在位置的 element。 即使已经移出了元素甚至移出了document, 它表示的element仍然不变
3.tap类触碰事件
实际开发使用这类事件比较少,一般用来替代click事件
tap: 手指碰一下屏幕会触发
longTap: 手指长按屏幕会触发
singleTap: 手指碰一下屏幕会触发
doubleTap: 手指双击屏幕会触发
swipe类滑动事件
swipe:手指在屏幕上滑动时会触发
swipeLeft:手指在屏幕上向左滑动时会触发
swipeRight:手指在屏幕上向右滑动时会触发
swipeUp:手指在屏幕上向上滑动时会触发
swipeDown:手指在屏幕上向下滑动时会触发
在移动端开发中通常会选择引用一个移动端事件插件来实现快速开发
比如在vue项目中选择vue-touch
npm insall vue-touch@next --save
然后再main.js中引入:
import VueTouch from 'vue-touch'
Vue.use(VueTouch, {name: 'v-touch'})
之后在任何组件内都可以按照下方的方式进行使用:
<template>
<div>
<v-touch v-on:swiperleft="left" v-on:swiperright="right" class="wrapper">
</v-touch>
</div>
</template>
7.移动端实现滑动一个dom结构
var div1 = document.querySelector('#div1');
//限制最大宽高,不让滑块出去
var maxW = document.body.clientWidth - div1.offsetWidth;
var maxH = document.body.clientHeight - div1.offsetHeight;
// 开始拖动时触摸点相对于div1左上顶点的坐标
var oL = 0
var oT = 0
//手指触摸开始,记录div的初始位置
div1.addEventListener('touchstart', function (e) {
var ev = e || window.event;
var touch = ev.targetTouches[0];
oL = touch.clientX - div1.offsetLeft;
oT = touch.clientY - div1.offsetTop;
});
//触摸中的,位置记录
div1.addEventListener('touchmove', function (e) {
var ev = e || window.event;
var touch = ev.targetTouches[0];
var oLeft = touch.clientX - oL;
var oTop = touch.clientY - oT;
if (oLeft < 0) {
oLeft = 0;
} else if (oLeft >= maxW) {
oLeft = maxW;
}
if (oTop < 0) {
oTop = 0;
} else if (oTop >= maxH) {
oTop = maxH;
}
div1.style.left = oLeft + 'px';
div1.style.top = oTop + 'px';
});
8.PWA是什么?,讲下核心点
渐进式网络应用程序(Progressive Web Application - PWA),是一种可以提供类似于原生应用程序(native app)体验的网络应用程序(web app)。PWA 可以用来做很多事。其中最重要的是,在离线(offline)时应用程序能够继续运行功能。这是通过使用名为 Service Workers 的网络技术来实现的。
核心技术:
- Web App Manifest – 在主屏幕添加app图标,定义手机标题栏颜色之类
- Service Worker – 缓存,离线开发,以及地理位置信息处理等
- App Shell – 先显示APP的主结构,再填充主数据,更快显示更好体验
- Push Notification – 消息推送
9.Weex?
Weex 致力于使开发者能基于通用跨平台的 Web 开发语言和开发经验,来构建 Android、iOS 和 Web 应用。简单来说,在集成了 WeexSDK 之后,你可以使用 JavaScript 语言和前端开发经验来开发移动应用。
一个重点领域是混合式APP开发,其中的知识点包括x5内核的优化,以及Android和H5的交互,IOS和H5的交互,暂时没有涉及,后面再进行学习。