移动端开发记录

h5适配计算

什么是viewport

早期移动端的viewport与pc的viewport是一个概念,导致小屏体验不佳,后来苹果引入可视视窗(visual viewport)和布局视窗(layout viewport)。这两个视窗是透视的效果,想象下layout viewport是一张大的不能改变大小和角度的图片。我们透过visual viewport对layout viewport进行观察。观察距离远点(用户的缩小页面功能)就可以一次性看到这个大图。或者近点(用户的放大页面功能)可以看到一部分。你能改变这个透视框的方向,但这张大图片的大小和形状都不会改变。

我们在<meta name="viewport" /> 设置的其实是layout-viewport,使得layout viewport==visual viewport,达到ideal viewport效果,使得viewport刚好完美覆盖屏幕,因此适配方案的时候,这一句最重要。

px rem vw的转换

  • 默认情况下根元素的font-size为 1rem = 16px,但为了方便换算,我们通常设置 1rem = 100px
  • 以750px的设计稿为例,则可以得出 750px = 7.5rem
  • 相当于100vw=7.5rem那么1rem = 100vw / 7.5 = 13.3333vw,所以设置根元素的font-size为13.3333vw
  • 而在页面样式中,直接将设计稿中的px除以100就是对应的rem值
  • 若要兼容旧浏览器,则需要写入响应式布局,例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    // 相当于 320 / 7.5 = 42.667px
    @media screen and (max-width: 320px) {
    html {
    font-size: 42.667px;
    font-size: 13.3333vw;
    }
    }

    // 相当于375 / 7.5 = 48px,以下同理
    @media screen and (min-width: 321px) and (max-width: 375px) {
    html {
    font-size: 48px;
    font-size: 13.3333vw;
    }
    }

    @media screen and (min-width: 376px) and (max-width:393px) {
    html {
    font-size: 52.4px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 394px) and (max-width:412px) {
    html {
    font-size: 54.93px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 413px) and (max-width:414px) {
    html {
    font-size: 55.2px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 415px) and (max-width:480px) {
    html {
    font-size: 64px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 481px) and (max-width:540px) {
    html {
    font-size: 72px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 541px) and (max-width:640px) {
    html {
    font-size: 85.33px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 641px) and (max-width:720px) {
    html {
    font-size: 96px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 721px) and (max-width:768px) {
    html {
    font-size: 102.4px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 769px) and (max-width:852px) {
    html {
    font-size: 113.4px;
    font-size: 13.3333vw
    }
    }
    @media screen and (min-width: 853px) {
    html {
    font-size: 130.4px;
    font-size: 13.3333vw
    }
    }

不同的设计稿,可以参考下面的表格

设计稿大小(单位 px) html 的 font-size(单位 vw)
375 26.666666
750 13.333333
320 31.25
640 15.625

viewport缩放比例设置

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

其他可能使用到的meta标签配置

1
2
3
4
5
6
<meta name="screen-orientation" content="portrait"> //Android 禁止屏幕旋转
<meta name="full-screen" content="yes"> //全屏显示
<meta name="browsermode" content="application"> //UC应用模式,使用了application这种应用模式后,页面讲默认全屏,禁止长按菜单,禁止收拾,标准排版,以及强制图片显示。
<meta name="x5-orientation" content="portrait"> //QQ强制竖屏
<meta name="x5-fullscreen" content="true"> //QQ强制全屏
<meta name="x5-page-mode" content="app"> //QQ应用模式

电话号码识别

在 iOS Safari (其他浏览器和 Android 均不会)上会对那些看起来像是电话号码的数字处理为电话链接,比如:

  • 7 位数字,形如:1234567
  • 带括号及加号的数字,形如:(+86)123456789
  • 双连接线的数字,形如:00-00-00111
  • 11 位数字,形如:13800138000

关闭识别

1
<meta name="format-detection" content="telephone=no" />

开启识别

1
<a href="tel:123456">123456</a>

邮箱识别(Android)

安卓上会对符合邮箱格式的字符串进行识别,我们可以通过如下的 meta 来管别邮箱的自动识别

1
<meta content="email=no" name="format-detection" />

同样地,我们也可以通过标签属性来开启长按邮箱地址弹出邮件发送的功能:

1
<a mailto:dooyoe@gmail.com">dooyoe@gmail.com</a>

chrome实机调试

  • 电脑上访问chrome://inspect/#devices
  • 在手机中安装Chrome浏览器
  • 若是调试微信内置网页,需要先在手机中打开这个地址:http://debugxweb.qq.com/?inspector=true
  • 安卓手机开启USB调试,通过USB连接电脑即可

底部使用固定定位遮住内容

给底部内容设置padding-bottom撑开

判断页面所在的环境

判断是否移动端

1
2
3
4
5
6
7
function isMobile(){
if(window.navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
return true; // 移动端
}else{
return false; // PC端
}
}

判断是否微信环境

1
2
3
4
5
function getIsWxClient() {
const ua = navigator.userAgent.toLowerCase();
const reg = /MicroMessenger/i;
return reg.test(ua);
}

判断是否横屏/竖屏

1
2
3
4
5
6
7
8
9
10
11
12
// 判断是否横屏竖屏
function hengshuping() {
// 竖屏
if (window.orientation == 180 || window.orientation == 0) {
alert('竖屏')
}
// 横屏
if (window.orientation == 90 || window.orientation == -90) {
alert('横屏')
}
}
window.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize',hengshuping,false);

判断是否IOS环境

1
2
3
4
function isIos() {
const u = navigator.userAgent;
return !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
}

判断浏览器环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
let isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

// Firefox 1.0+
let isFirefox = typeof InstallTrigger !== 'undefined';

// Safari 3.0+ "[object HTMLElementConstructor]"
let isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));

// Internet Explorer 6-11
let isIE = /*@cc_on!@*/false || !!document.documentMode;

// Edge 20+
let isEdge = !isIE && !!window.StyleMedia;

// Chrome 1 - 79
let isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);

// Edge (based on chromium) detection
let isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);

// Blink engine detection
let isBlink = (isChrome || isOpera) && !!window.CSS;


let output = 'Detecting browsers by ducktyping:<hr>';
output += 'isFirefox: ' + isFirefox + '<br>';
output += 'isChrome: ' + isChrome + '<br>';
output += 'isSafari: ' + isSafari + '<br>';
output += 'isOpera: ' + isOpera + '<br>';
output += 'isIE: ' + isIE + '<br>';
output += 'isEdge: ' + isEdge + '<br>';
output += 'isEdgeChromium: ' + isEdgeChromium + '<br>';
output += 'isBlink: ' + isBlink + '<br>';
document.body.innerHTML = output;

iphone字体重叠问题

在iphone8下设置字体容器的宽度,发现字体会重叠,将容器宽度取消,问题解决

移动端获取scrollTop高度

不同手机的浏览器获取scrollTop存在兼容问题,需要取几个可能取到的属性的最大值

1
2
const scrollTop = Math.max(document.documentElement.scrollTop,document.body.scrollTop,window.scrollY);
const scrollHeight = Math.max(document.documentElement.scrollHeight || document.body.scrollHeight)

关于小米手机自带浏览器背景图加载失败

自带浏览器可能对一些字段进行了屏蔽(例如广告之类的),在对图片进行命名时,尽量简单命名,避开某些关键字

scss less移动端函数转换

1
2
3
4
// scss
@function pxToRem($size) {
@return calc($size / 100) * 1rem
}
1
2
3
4
5
6
7
8
9
// less
.pxToRem(@px) {
@var: unit(@px / 100)
@rem: ~'@{var}rem'
}
// 使用
.box {
width: .pxToRem(300px)[@rem]
}

Comments