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" />
|
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实机调试
底部使用固定定位遮住内容
给底部内容设置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; } }
|
判断是否微信环境
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;
let isFirefox = typeof InstallTrigger !== 'undefined';
let isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));
let isIE = false || !!document.documentMode;
let isEdge = !isIE && !!window.StyleMedia;
let isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
let isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);
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存在兼容问题,需要取几个可能取到的属性的最大值
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
| @function pxToRem($size) { @return calc($size / 100) * 1rem }
|
1 2 3 4 5 6 7 8 9
| .pxToRem(@px) { @var: unit(@px / 100) @rem: ~'@{var}rem' }
.box { width: .pxToRem(300px)[@rem] }
|