[TOC]

手机端页面开发

1. 高清方案布局代码

这是阿里团队的高清方案布局代码,所谓高清方案就是利用rem的特性(我们知道默认情况下html的1rem = 16px),根据设备屏幕的DPR(设备像素比,又称DPPX,比如dpr=2时,表示1个CSS像素由4个物理像素点组成)根据设备DPR调整页面的压缩比率(即:1/dpr),同时动态设置 html 的font-size为(50 * dpr),进而达到高清效果

<script>!function(e){function t(a){if(i[a])return i[a].exports;var n=i[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var i={};return t.m=e,t.c=i,t.p="",t(0)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var i=window;t["default"]=i.flex=function(normal,e,t){var a=e||100,n=t||1,r=i.document,o=navigator.userAgent,d=o.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i),l=o.match(/U3\/((\d+|\.){5,})/i),c=l&&parseInt(l[1].split(".").join(""),10)>=80,p=navigator.appVersion.match(/(iphone|ipad|ipod)/gi),s=i.devicePixelRatio||1;p||d&&d[1]>534||c||(s=1);var u=normal?1:1/s,m=r.querySelector('meta[name="viewport"]');m||(m=r.createElement("meta"),m.setAttribute("name","viewport"),r.head.appendChild(m)),m.setAttribute("content","width=device-width,user-scalable=no,initial-scale="+u+",maximum-scale="+u+",minimum-scale="+u),r.documentElement.style.fontSize=normal?"50px": a/2*s*n+"px"},e.exports=t["default"]}]);  flex(false,100, 1);</script>

1.1 高清方案源代码

源码:绝不是每个地方都要用rem,rem只适用于固定尺寸!

'use strict';
/**
 * @param {Boolean} [normal = false] - 默认开启页面压缩以使页面高清;  
 * @param {Number} [baseFontSize = 100] - 基础fontSize, 默认100px;
 * @param {Number} [fontscale = 1] - 有的业务希望能放大一定比例的字体;
 */
const win = window;
export default win.flex = (normal, baseFontSize, fontscale) => {
  const _baseFontSize = baseFontSize || 100;
  const _fontscale = fontscale || 1;

  const doc = win.document;
  const ua = navigator.userAgent;
  const matches = ua.match(/Android[\S\s]+AppleWebkit\/(\d{3})/i);
  const UCversion = ua.match(/U3\/((\d+|\.){5,})/i);
  const isUCHd = UCversion && parseInt(UCversion[1].split('.').join(''), 10) >= 80;
  const isIos = navigator.appVersion.match(/(iphone|ipad|ipod)/gi);
  let dpr = win.devicePixelRatio || 1;
  if (!isIos && !(matches && matches[1] > 534) && !isUCHd) {
    // 如果非iOS, 非Android4.3以上, 非UC内核, 就不执行高清, dpr设为1;
    dpr = 1;
  }
  const scale = normal ? 1 : 1 / dpr;

  let metaEl = doc.querySelector('meta[name="viewport"]');
  if (!metaEl) {
    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    doc.head.appendChild(metaEl);
  }
  metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
  doc.documentElement.style.fontSize = normal ? '50px' : `${_baseFontSize / 2 * dpr * _fontscale}px`;
};

1.2 CSS中px和em的数值可以精确到小数点后几位

引用 《CSS权威指南》(第三版) P84

CSS中有两类数字:整数(“完整”的数)和实数(小数)。这些数字类型主要作为其他值类型的基础,不过在某些情况下,这些基本类型数字也可以用做属性的值

在CSS2.1中,实数定义为一个整数后可以跟有一个小数点和小数部分。因此,以下都是合法的数字值:15.5-270.000045。整数和实数都可以是正数或负数,不过属性可能(而且通常会)限制所允许的数字范围

从本段话中的理解是CSS中单位pxem数值的小数点是无限制的,不过CSS不同的属性会限制其允许范围,而且在使用小数点时,也会存在一些浏览器解析差异的问题:

.container{  
    width:10.9px;  
    height:6.2px;
}  

IE8 中会显示当前的宽度为11px,而在 IE7 会以10px进行显示; 所以对于小数点的使用不同浏览器会存在不同的解析方式:

  1. 采用四舍五入解析的浏览器:IE8、IE9、Chrome、Firefox
  2. 采用直接取整解析的浏览器:IE7、Safari

2. 手机浏览器兼容性

2.1 部分手机浏览器不支持dom类数组的forEach功能

我在开发的过程中,使用document.querySelectorAll(".tab .tab-header>li")获取一组类数组对象的时候,使用forEach遍历每个对象的时候,在一些旧版本的手机浏览器中发现出错:

var tabHeaders = document.querySelectorAll(".tab .tab-header>li");
tabHeaders.forEach(function(tab){
   tab.onclick = function() {
       // 做一些操作
   }
}

上面的代码在UC浏览器手机版本(V11.9.6.1) 会报错。想要遍历可以使用for循环:

for (var i = 0; i < tabHeaders.length; i++) {
    tabHeaders[i].onclick = function() {
        // 做一些操作
    }
}

2.2 部分手机浏览器不支持ES6语法高级语法

在开发的时候在代码中使用了let变量,但是在部分浏览器(华为手机自带浏览器2018-06-06)中发现出错,导致整个JS文件都没有执行:

for (let i = 0; i < tabHeaders.length; i++) {}

上面的代码for循环中使用了let声明变量,导致我在华为手机自带的浏览器中页面没有执行JS文件。 解决办法是把let 换成var,即可。

还有ES6的字符串:

var str = `1、挖掘用户需求,收集数据反馈,进行数据分析 <br>
2、参与课程信息收集、研发工作
`

这样的字符串也会在华为自带浏览器报错,可以把多行字符串写成下面:

var str = "1、北京高校在校生,专业不限,一周可实习至少4天,能够全职实习最好 	<br>\
2、工作踏实、细致、耐心、积极、负责,学习能力强,拥抱变化 	<br>\
3、良好的团队合作意识和创新意识<br>\
"

注意,反斜杠的后面必须是换行符,而不能有其他字符(比如空格),否则会报错。

所以为了兼容性,页面中的JS中不要是用ES6以上的高级语法。

3. 移动设备常用的meta标签

3.1 viewport (虚拟视窗)

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

width=device-width: 宽度=设备宽度

initial-scale=1.0:初始缩放比例

maximum-scale=1.0:允许用户放大到的最大比例

user-scalable=no:yes或者no来指定是否允许用户手动缩放

3.2 MobileOptimized:为某个宽度特殊优化

<meta name="MobileOptimized" content="320" />

告诉浏览器页面为某个宽度特殊优化 (微软系)

3.3 HandheldFriendly:是否为手持设备优化

<meta name="HandheldFriendly" content="true" />

告诉浏览器页面是否为手持设备优化,会被MobileOptimized覆盖 (旧浏览器和功能机上某些浏览器识别)

3.4 Apple私有

3.4.1 apple-mobile-web-app-capable:隐藏工具栏和菜单栏

<meta name="apple-mobile-web-app-capable" content="yes" />

启用webapp模式,会隐藏工具栏和菜单栏

3.4.2 apple-mobile-web-app-status-bar-style:定义顶栏的颜色

<meta name="apple-mobile-web-app-status-bar-style" content="black" />

启用webapp模式后,定义顶栏的颜色,值为default(白色) | black(黑色) | black-translucent(半透明)

3.5 format-detection:电话号码和邮箱识别

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

format-detection翻译成中文的意思是“格式检测”,顾名思义,它是用来检测html里的一些格式的,那关于meta的format-detection属性主要是有以下几个设置:

meta name="format-detection" content="telephone=no"

meta name="format-detection" content="email=no"

meta name="format-detection" content="adress=no"

也可以连写:meta name="format-detection" content="telephone=no,email=no,adress=no"

  • telephone

    你明明写的一串数字没加链接样式,而iPhone会自动把你这个文字加链接样式、并且点击这个数字还会自动拨号!想去掉这个拨号链接该如何操作呢?这时我们的meta又该大显神通了,代码如下:

    telephone=no就禁止了把数字转化为拨号链接! telephone=yes就开启了把数字转化为拨号链接,要开启转化功能,这个meta就不用写了,在默认是情况下就是开启!

  • email

    告诉设备不识别邮箱,点击之后不自动发送

    email=no禁止作为邮箱地址! email=yes就开启了把文字默认为邮箱地址,这个meta就不用写了,在默认是情况下就是开启!

  • adress

    adress=no禁止跳转至地图! adress=yes就开启了点击地址直接跳转至地图的功能,在默认是情况下就是开启!

http://blog.sina.com.cn/s/blog_51048da70101cgea.html

3.6 target-densitydpi:屏幕像素密度

target-densitydpi = [dpi_value | device-dpi | high-dpi | medium-dpi | low-dpi]

安卓设备上viewport的属性,对应屏幕像素密度 (低像素密度,中像素密度,高像素密度),无特殊情况不建议使用。

3.7 baidu-site-verification:百度站长平台验证

<meta name="baidu-site-verification" content="AwZm789POz" />

当你添加一个网站后,百度需要验证网站是否为你所有,就会提供几种验证方式,你的这个代码就是一种验证方式。

验证过后可以删除,没什么用。也可以保留,不影响网站任何使用。

3.7.1 verify-v1或google-site-verification或sogou-site-verification类似

Google的验证:
meta name="verify-v1"
meta name="google-site-verification"

https://www.cnblogs.com/chunshu/p/5448315.html

4. 其他功能

4.1 禁止手机横屏

有时希望手机禁止横屏浏览网页,而横屏这个功能一般在手机或手机浏览器上设置,作为网页是没有权限去操作这个设置了。

那么页面中发现是横屏的办法:

1、通过判断窗口宽高值的比值判断是否横屏

对于正常手机屏幕来说,窗口宽度是小于窗口高度的,即 宽度/高度 的值是小于 1 的,那么如果手机横屏了呢,窗口原本的宽度变成了高度,原本的高度变成了宽度,此时, 宽高比就大于 1 了。以此来判断手机是否横屏。

function rotate (){
    if(document.documentElement.clientWidth > document.documentElement.clientHeight){
        alert('横屏了');
    }else{
        alert('没有横屏');
    }
}
window.onload = rotate;
window.onresize = rotate;

但是,对于手机端的页面 ,一般 window.onload 和 window.onresize 两个事件都会被占用来做其他的事情,如果想这样写,就得在js中穿插 rotate 函数中的代码,使代码变得不那么规整。

2、通过 orientationchange 事件判断是否横屏

orientationchange 为html5的新特性,是在用户水平或者垂直翻转设备(即方向发生变化)时触发的事件,而且这个事件一般不会被占用。

核心代码如下:

window.onorientationchange=function(){
    if(window.orientation==90||window.orientation==-90){
        alert('横屏了');
    }else{
        alert('没有横屏');
    }
}

我们可以利用这个方法封装成一个自执行的js ,只要有用到,直接引用就可以了

参考资料:移动端开发-禁止横屏

4.2 网页拨打电话

1、a链接拨打(支持大部分的浏览器,但是在qq浏览器上支持不好):

<a href="tel:10086">马上拨打电话10086</a>

2、a链接(这种方式塞班、安卓、iphone都支持):

<a href="tel://10086">马上拨打电话10086</a>

采用url链接的方式,实现在safari ios,android 浏览器,webos 浏览器,塞班浏览器,ie,operamini等主流浏览器,进行拨打电话功能。

3、使用wtai协议进行拨打电话:

<a href="wtai://wp//mc;10086">拨打10086 </a>  
<a href="wtai://wp/ap;10086;">存储</a> 

在wml中可以调用设备的wtai函数来呼叫特定的电话号码。目前,越来越多的浏览器都支持这个功能,但还不是所有。

4、使用点击事件实现(需要验证):

// 是否ios浏览器
const isIosBrowser = (() => {
  let isIos = null;
  return () => {
    if (isIos === null) {
      isIos = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    }
    return isIos;
  };
})();

// 拨打电话
function callNumber(number) {
  if (isIosBrowser) { // IOS系统需要使用a链接手动触发
    let a = document.createElement('a');
    a.href = 'tel:' + number;
    a.style.visibility = 'hidden';
    document.body.appendChild(a);
    a.click();
  } else {
    window.location.href = 'tel:' + number;
  }
}

关于微信页面会出现屏蔽的方式,所以采取以下解决方案

解决方法如下: 1、拨号的代码还是不变,和原先的一样, 2、打开拨号页面要做下处理,在网址后面增加一个锚节点mp.weixin.qq.com。 实例如下: 如:<a href="tel:10086">一键拨号</a> 上需要拨号代码,操作如下 在有这个代码的页面URl后边加上#mp.weixin.qq.com 如:tel:10086#mp.weixin.qq.com

https://www.cnblogs.com/lxwphp/p/8779019.html

4.3 网页发送短信

https://blog.csdn.net/WilliamsWayne/article/details/81014733

1、不添加内容:

<a href="sms:10086">发送短信</a>

2、添加内容,iOS系统用&

<a href="sms=139XXXXXXXX&body=短信内容">要显示的文字</a>

3、添加内容,Android系统用?:

<a href="sms=189XXXXXXXX?body=短信内容">要显示的文字</a>

4、通过点击事件实现:

// 添加内容
window.location.href = 'sms:10086?body=短信内容';
// 不添加内容
window.location.href = 'sms:10086';

4.4 网页发邮件

<a href="mailto:fakemail@XXX.com?subject=say hello" >要显示的文字</a>

参考资料

手机端页面自适应解决方案—rem布局进阶版(附源码示例)

JS来判断页面是在手机端还是在PC端打开的方法

简单的利用JS来判断页面是在手机端还是在PC端打开的方法

手机浏览器User-Agent信息

手机版头部声明细则 CSDN

移动前端常用的html5 head标签

移动设备的那些meta标签们

Last Updated: 9/9/2021, 3:49:55 PM