一、使用真实手机测试未发布网页的方法
方法① 在虚拟机中搭建xampp,将文件通过FTP传到虚拟机,在一个局域网中,用手机访问虚拟机的IP地址
特点: 繁琐、可调试PHP
方法② 使用Fiddler用手机访问http://127.0.0.1进行访问
特点: 有些公众号无法使用Fiddler打开
方法② 放在nginx的html跟目录改为项目的目录,用手机通过局域网访问电脑的IP地址,可调试网页
特点: 相对简单,不可调试PHP
方法③ 将WebStorm的http://localhost:63342改为http://127.0.0.1:63342,用手机通过Fiddler访问
特点: 最简单,不可调试PHP,无法在微信中打开(除非额外配置(修改端口),使其可在局域网打开)
调试手机中页面的方法
方法① 使用Chrome DevTools远程调试Android和iOS页面
特点: 可调试需要用微信浏览器打开的页面
参考: https://juejin.im/entry/5afd1b276fb9a07acc11ec81?utm_medium=fe&utm_source=weixinqun
步骤: 1、chrome浏览器翻墙,在地址栏输入: chrome://inspect
2、手机和电脑用usb连接,打开USB调试
3、在手机上打开网页,电脑上可显示此手机打开的页面,点击当前显示的页面下的inspect即可
注意: 有些app里的网页无法显示网址,不支持调试
有些时候不能正常显示网址,重新插拔数据线即可
方法② 使用Mac 调试 IOS 系统的 Safari 浏览器
步骤:
1、打开苹果手机→设置→Safari浏览器→高级→Web检查器
2、打开 Mac 上的 Safari浏览器→偏好设置→高级→在菜单栏中显示'开发'菜单
3、用数据线连接 Mac 电脑和苹果手机→选择信任设备→在手机的 Safari浏览器 中打开需要调试的页面→在电脑上点击开发→**的iPhone→打开调试的网址→打开调试界面
方法③ 使用vconsole
https://github.com/Tencent/vConsole//vConsole文档
vConsole是一个轻量、可拓展、针对手机网页的前端开发者调试面板
特性
① 查看console日志
② 查看网络请求
③ 查看页面element结构
④ 查看Cookies和localStorage
⑤ 手动执行JS命令行
⑥ 自定义插件
开启vconsole:
<script src="http://wechatfe.github.io/vconsole/lib/vconsole.min.js?v=3.2.0"></script>
<script>
var vConsole = new VConsole(); //初始化
console.log('Hello world');
</script>
http://debugx5.qq.com 微信浏览器清除缓存的网址,勾选需要清除的选项即可
也可以开启vconsole
方法④ 适用于Safari
浏览器设置: Safari→偏好设置→高级→勾选"在菜单栏中显示开发"菜单
iphone设置: 设置→Safari→高级→打开 Web 检查器
方法⑤ iOS模拟器: 不需要真机,适合调试Webview和H5有频繁交互的功能页面
下载Xcode→运行项目→选择模拟器iphonex→编译后就会打开模拟器
微信浏览器是在webview的上层做的缓存:如果请求过了这个地址,就会存在本地,之后就不取线上的了
在调试阶段或者频繁更新的页面加入以下头信息可防止缓存(有些手机无效)
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
移动端弹出键盘时,fixed定位在底部的内容依然会固定出现在键盘上方
建议在移动端的基础样式中设置 white-space:nowrap; 在个别元素上允许换行
在ios中,最下面的margin-bottom可能会不起作用,建议换成padding-bottom
注意: 在移动端,运行js时,*.gif、css动画可能会暂停,无法完整显示加载中
var obj={id:"1", value:"5"};
alert(JSON.stringify(obj)); //将对象转换为json字符串可用于移动端调试
如:
try{
可能出错的语句(执行语句)
}catch(err){
alert(JSON.stringify(err)); //或: alert(err.message)
}
_______________________________________________________________________________________________
二、移动端设置视口及其它meta(通用)
① <meta charset="UTF-8"> //设置网页的编码格式
②<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
//必备,WebStorm快捷键meta:vp
或<meta name="viewport" content="initial-scale=1.0, minimum-scale=0.5, maximum-scale=1.0,
user-scalable=yes" />
width=device-width: 屏幕的宽等于分辨率的宽
initial-scale=1: 指定视口的初始化缩放倍率为1
user-scalable=no/0: 不允许用于手动缩放网页,yes/1允许缩放
设置为no后,minimum-scale 和 maximum-scale都将被忽略,因为不可能缩放
③ <meta name="format-detection" content="telephone=no" /> //禁止iPhone把数字识别为电话号码
④ <meta name="format-detection" content="email=no" /> //忽略Android对邮箱地址的识别
⑤ <meta name="format-detection" content="adress=no" /> //点击地址后,禁止跳转至地图
<meta name="format-detection" content="telephone=no,email=no,adress=no" /> //③④⑤的简写
⑥ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> //在360等双核浏览器中强制使用最新的内核渲染页面
target-densitydpi=device-dpi: 屏幕像素密度,每英寸点的数量(dpi)
取值范围:
device-dpi: 使用设备原本的dpi作为目标dpi,不会发生默认缩放
high-dpi: 使用hdpi作为目标dpi,中等像素密度和低像素密度设备相应缩小
medium-dpi: 使用mdpi作为目标dpi,高像素密度设备相应放大,低像素密度设备相应缩小(默认)
low-dpi: 使用ldpi作为目标dpi,中等像素密度和高像素密度设备相应放大
整数数字: 指定一个具体的dpi值作为target dpi,必须在70–400之间
注:① 为防止Android Browser和WebView根据不同屏幕的像素密度对页面缩放,可将viewport的target-densitydpi设置为device-dpi(否则页面会根据当前屏幕的像素密度进行展示),同时还需要将viewport的 width定义为与设备的width匹配,这样页面就可以和屏幕相适应
② 为了兼容性考虑,Android 4.4 以上抛弃了target-densitydpi属性,它只在Android旧设备上生效
网页的框架(灰色的可酌情添加,更浅的在PC端使用)
<html>
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
<meta name="format-detection" content="telephone=no,email=no,adress=no"/>
<meta http-equiv="x-dns-prefetch-control" content="on"/>
<link rel="dns-prefetch" href="//api.m.taobao.com">
<!-- Set render engine for 360 browser -->
<meta name="renderer" content="webkit">
<!-- No Baidu Siteapp-->
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<!-- Add to homescreen for Chrome on Android -->
<meta name="mobile-web-app-capable" content="yes">
<!-- Add to homescreen for Safari on iOS -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="myApp"/>
<!-- Tile icon for Win8 (tile color) -->
<meta name="msapplication-TileColor" content="#0e90d2">
<meta name="theme-color" content="#0096ff" />
<title>myApp</title>
<link rel="stylesheet" href="assets/css/app.css"></head>
<body>
<!--在这里编写代码-->
<!--[if (gte IE 9)|!(IE)]><!-->
<script src="assets/js/jquery.min.js"></script>
<!--<![endif]-->
<!--[if lte IE 8 ]>
<script src="http://libs.baidu.com/jquery/1.11.3/jquery.min.js"></script>
<script src="http://cdn.staticfile.org/modernizr/2.8.3/modernizr.js"></script>
<script src="assets/js/amazeui.ie8polyfill.min.js"></script>
<![endif]-->
<script src="assets/js/app.js"></script>
</body>
</html>
注意:favicon.ico使用服务器上的即可,不需要使用link标签
<link rel="icon" href="static/images/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="static/images/favicon.ico" type="image/x-icon" />
三、CSS3 Media Query 媒体查询技术:
@media not/only MEDIA-TYPE and (MEDIA-FEATURE){ CSS样式规则 } //不要忘记加空格
MEDIA-TYPE: 媒体类型
取值:
① all: 所有设备(默认值)
② screen: 屏幕,电脑、手机、平板电脑的屏幕
③ tv: 电视设备
MEDIA-FEATURE: 媒体特性
取值:
① width: 指定浏览器的窗口宽度是否为指定的数值(手机屏幕一般为320px-580px)
② min-width: 指定浏览器宽度的最小值
③ max-width: 指定浏览器宽度的最大值
JS的计算方式:
document.documentElement.style.fontSize = document.documentElement.clientWidth/32+ 'px';
// 32: iPhone6/7/8(宽375px)下,1rem = 11.71875px
CSS的形式:
@media screen and (min-width: 320px) and (max-width: 359px) {html{font-size:10px;}}
@media screen and (min-width: 360px) and (max-width: 374px) {html{font-size:11.25px;}}
@media screen and (min-width: 375px) and (max-width: 399px) {html{font-size:11.71875px;}}
@media screen and (min-width: 400px) and (max-width: 413px) {html{font-size:12.5px;}}
@media screen and (min-width: 414px) and (max-width: 439px) {html{font-size:12.9375px;}}
@media screen and (min-width: 440px) and (max-width: 479px) {html{font-size:13.75px;}}
@media screen and (min-width: 480px) and (max-width: 519px) {html{font-size:15px;}}
@media screen and (min-width: 520px) and (max-width: 559px) {html{font-size:16.25px;}}
@media screen and (min-width: 560px) and (max-width: 599px) {html{font-size:17.5px;}}
@media screen and (min-width: 600px) and (max-width: 639px) {html{font-size:18.75px;}}
@media screen and (min-width: 640px) and (max-width: 679px) {html{font-size:20px;}}
@media screen and (min-width: 680px) and (max-width: 719px) {html{font-size:21.25px;}}
@media screen and (min-width: 720px) and (max-width: 759px) {html{font-size:22.5px;}}
@media screen and (min-width: 760px) and (max-width: 799px) {html{font-size:23.75px;}}
@media screen and (min-width: 800px) and (max-width: 839px) {html{font-size:25px;}}
@media screen and (min-width: 840px) and (max-width: 879px) {html{font-size:26.25px;}}
@media screen and (min-width: 880px) and (max-width: 919px) {html{font-size:27.5px;}}
@media screen and (min-width: 920px) and (max-width: 959px) {html{font-size:28.75px;}}
@media screen and (min-width: 960px) and (max-width: 999px) {html{font-size:30px;}}
@media screen and (min-width: 1000px) and (max-width: 1039px) {html{font-size:31.25px;}}
@media screen and (min-width: 1040px) and (max-width: 1079px) {html{font-size:32.5px;}}
@media screen and (min-width: 1080px) and (max-width: 1119px) {html{font-size:33.75px;}}
@media screen and (min-width: 1120px) and (max-width: 1159px) {html{font-size:35px;}}
@media screen and (min-width: 1160px) {html{font-size:36.25px;}}
JS的计算方式:
动态计算屏幕的宽度,得到网页的根字体大小,并限定最大的rem
(function(doc, win){
var docEl = doc.documentElement;
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
var recalc = function(){
var clientWidth = docEl.clientWidth;
if(!clientWidth) return false;
if(clientWidth > 750) clientWidth=750; //限制最大的宽度尺寸,限定最大rem
docEl.style.fontSize =clientWidth / 32+ 'px';
};
if (!doc.addEventListener) return false;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
移动端开发过程中,因为手机的dpr(设备像素比不同),需要根据dpr来修改图标的大小
通过@media(媒体查询),判断设备的dpr,动态修改图标的背景图片
.bg_img{
width: 1rem;
height: 1rem;
background-image: url("../img/questionnaire.png");
background-repeat: no-repeat;
background-position: center;
background-size: contain;
}
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){
.bg_img{
background-image: url("../img/questionnaire@2x.png");
}
}
@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3){
.bg_img{
background-image: url("../img/questionnaire@3x.png");
}
}
_______________________________________________________________________________________________
四、字体:
ios 系统
默认中文字体是Heiti SC
默认英文字体是Helvetica
默认数字字体是HelveticaNeue
无微软雅黑字体
android 系统
默认中文字体是Droidsansfallback
默认英文和数字字体是Droid Sans
无微软雅黑字体
winphone 系统
默认中文字体是Dengxian(方正等线体)
默认英文和数字字体是Segoe
无微软雅黑字体
注: 如无特殊需求,手机端无需定义中文字体,使用系统默认即可
英文字体和数字字体可使用 Helvetica,三种系统都支持
代码: body{ font-family:-apple-system-font,Helvetica Neue,Helvetica,sans-serif; }
或 body{ font-family:"Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; }
_______________________________________________________________________________________________
CSS3中的单位(浏览器默认字体为16px):
注意:chrome强制最小字体为12号,即使设置成10px也会显示成12px,即使把html的font-size设置成10px,子节点rem的计算还是以12px为基准,但可以使用viewport设置缩放比来调整字体,其它浏览器无限制
移动端字体最小可设置为8px(有些机型最小可设置1px,移动端chrome限制同样为12px)
px: 绝对单位,页面按精确像素展示
em: 相对单位,基准点为父节点字体的大小,如果自身定义了font-size则按自身计算
rem: 相对单位,相对根节点html的字体大小来计算
页面基准320px(20px),html的font-size值的计算:
document.getElementsByTagName('html')[0].style.fontSize=document.body.clientWidth/16+"px"
需设置meta视口:
vw: viewpoint width,视窗宽度,1vw等于视窗宽度的1%
vh: viewpoint height,视窗高度,1vh等于视窗高度的1%
vmin: vw和vh中较小的那个
vmax: vw和vh中较大的那个
vw,vh,vmin,vmax: IE9+局部支持,chrome/firefox/safari/opera支持,ios safari 8+支持,android browser4.4+支持,chrome for android39支持
适配方案(在微信中滚动时可能会卡顿):
html{
font-size: 3.1250133333vw;/* 100vw/375 ==3.1250133333vw/11.7188 */
}
注意: 可用于解决页面内容已加载,但设置字体的js还未执行时的字体闪烁问题
其它单位:
%: 百分比
in: 寸
cm: 厘米
mm: 毫米
pt: point,大约1/72寸
pc: pica,大约6pt,1/6寸
设计师常常给的是物理分辨率,程序中用到的是逻辑分辨率
物理分辨率是硬件所支持的分辨率,逻辑分辨率是软件可以达到的分辨率
比如: iphone6的分辨率写着375*667,指的是逻辑分辨率,而设计师设计稿上的750*1334是物理分辨率
物理分辨率/逻辑分辨率 = 像素倍率dpr,也就是常说的几倍屏
iphone6的像素倍率 = (750*1334)/(375*667) = 2
在移动端,直接写1px,会显示为逻辑分辨率1px,在2dpr屏幕下,物理分辨率是2px,在3dpr下,是3px
所以需要对屏幕或此线条进行缩放,使之变为1px
设置dpr,对视口进行缩放
var isAndroid = window.navigator.appVersion.match(/android/gi);
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var devicePR = window.devicePixelRatio;
var dpr = 1;
if(isAndroid || isIPhone){ //Android、iOS下,对于2、3的屏,用2、3倍的方案,其余用1倍方案
if(devicePR >= 3){
dpr = 3;
}else if(devicePR >= 2){
dpr = 2;
}
}
var scale = 1/dpr;
var meta = document.createElement('meta');
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', 'width=device-width,initial-scale='+scale+',user-scalable=no');
document.head.appendChild(meta);
document.documentElement.style.fontSize = innerWidth/32 + 'px';
//设置rem(iPhone6下,1rem = 23.4375px)
或者对线条进行缩放: 可使用元素生成,对生成的线条进行缩放
.bor_after_bottom{
position: relative;
}
.bor_after_bottom:after{
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background-color: red;
}
@media (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5){
.bor_after_bottom:after{
-webkit-transform: scaleY(0.66667);
transform: scaleY(0.66667);
}
}
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){
.bor_after_bottom:after{
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3){
.bor_after_bottom:after{
-webkit-transform: scaleY(0.33333);
transform: scaleY(0.33333);
}
}
也可以直接缩放内容生成元素
.weui_btn:after{
content: "";
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid rgba(0, 0, 0, 0.2);
-webkit-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
box-sizing: border-box;
}
@media (-webkit-min-device-pixel-ratio: 1.5),(min-device-pixel-ratio: 1.5){
.weui_btn:after{
-webkit-transform: scale(0.66667);
transform: scale(0.66667);
}
}
@media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2){
.weui_btn:after{
-webkit-transform: scale(0.5);
transform: scale(0.5);
}
}
@media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3){
.weui_btn:after{
-webkit-transform: scale(0.33333);
transform: scale(0.33333);
}
}
_______________________________________________________________________________________________
五、用户点击一个链接,会出现一个半透明灰色遮罩, 禁用方法:———或者直接使用div标签
a,button,input,textarea{-webkit-tap-highlight-color: rgba(0,0,0,0)} //iOS/Android系统
<meta name="msapplication-tap-highlight" content="no"> //winphone系统
span:active,span:focus{ background-color: #B4DEF3; } //在点击元素(或Tab时)时添加一个遮罩层
<input type="text"/> //文本框,弹出汉字键盘
<input type="password"/> //密码框,弹出汉字键盘
<input type="tel"/> //电话,弹出数字键盘
<input type="number" /> //数字,弹出数字键盘,只能输入数字 + - .等
<input type="url"/> //网址,弹出英文键盘
<input type="search"/> //搜索,弹出英文键盘,有些浏览器会显示个×
<input type="range" min="5" max="100" step="1"/> //范围,定义滑块控件
$('input').focus(); //使光标聚焦于此输入框
$('input').blur(); //使光标离开输入框,可以自动隐藏手机端软键盘
_______________________________________________________________________________________________
六、点击链接自动调用相关功能
<a href="tel:10086">打电话给: 10086</a> //打电话
<a href="sms:10086">发短信给: 10086</a> //发短信,winphone系统无效
<a href="mailto:10086@163.com">10086@163.com</a> //写邮件,自动调用默认客户端电子邮件程序
在某些Android内嵌网页上,即使在head设置<meta name="format-detection" content="telephone=no" />,仍然无法避免调取电话,可以设置 "禁止用户选中文本" 来避免调用电话
div{ -webkit-user-select:none; -ms-user-select:none; -moz-user-select:none;
-o-user-select:none; user-select:none; }
_______________________________________________________________________________________________
七、屏幕旋转的事件和样式
属性: window.orientation
取值: 正负90表示横屏模式;0和180表现为竖屏模式
window.onorientationchange = function(){ //当手机屏幕旋转时,自动触发此函数
switch(window.orientation){
case -90:
case 90: alert("横屏:" + window.orientation);
case 0:
case 180: alert("竖屏:" + window.orientation);
break;
}
}
CSS样式:
@media all and (orientation:portrait) { } //竖屏时使用的样式
@media all and (orientation:landscape) { } //横屏时使用的样式
_______________________________________________________________________________________________
八、audio元素和video元素在ios和andriod中无法自动播放
解决方案: 触屏即播
$('html').one('touchstart', function(){
audio.play()
})
九、HTML5 deviceMotion事件: 封装了运动传感器数据的事件,可获取手机运动状态下的运动加速度等数据
http://peunzhang.github.io/demo/deviceMotion/index.html 体验Demo
十、手机拍照和上传图片
利用<input type="file">的accept属性
<input type=file accept="image/*"> //选择照片
<input type=file accept="video/*"> //选择视频
accept属性可以用来限制用户上传文件的类型,在iOS和OSX中支持的很好
multiple属性可以选择多个文件,可以配合FormData对象,显示批量上传
_______________________________________________________________________________________________
十一、兼容移动端,只允许输入整数
方法①
$("input").keyup(function(){
var $this=$(this);
var val=$this.val();
if(val===""){
$this.val("");
return false; //不需要重新计算,同时退出函数
}else if(isNaN(val) || val.slice(0,1)==="0" || val===" " ||val<1){ //可能会是'00'
val=1;
}else if(val>99){
val=99;
}
$this.val(parseInt(val)); //去掉小数点(必须是type="tel/text"才能去掉)
//type="tel/number",点击时可弹出数字键盘
return true; //需要重新计算
})
$("body").on("change", function(e){ //防止动态加载的输入框无法绑定事件
var $target=$(e.target);
if($target.is("input[type=tel/text]")){
if($target.val() <= 0){ //若输入框为空,则 $this.val()==0 成立(number类型的0)
$target.val(1);
//若每次输入都更换元素,则用以下方式调整其值(重新生成元素之后)
//var val=$input.val(); //保存输入框的值
//if(val<1) val=1;
//$input.val("").focus().val(val); //清空,聚焦于此输入框,再赋值,使光标位于文字右侧
}else{
$target.val(parseInt($target.val())); //防止用户黏贴
}
}
})
方法②
$(".betting input").keyup(function(){ //keyup事件处理
var $this = $(this);
$this.val($this.val().replace(/\D|^0/g, ''));
if($this.val() > 999){
$this.val(999);
}
}).bind("paste", function(){ //Ctrl+V事件处理
$(this).val($(this).val().replace(/\D|^0/g, ''));
}).css("ime-mode", "disabled"); //CSS设置输入法不可用
注意:
① type="tel/text" 才能去掉小数点
type="tel/number" 点击时可弹出数字键盘
② 取值时,应考虑当输入框为空时,值设为1
属性: ime-mode 设置或检索是否允许用户激活输入中文,韩文,日文等输入法(IME)状态
值: disabled 完全禁用ime,对于有焦点的控件(如输入框),用户不可以激活ime
input输入框、加、减的样式
<div class="enter">
<span>追</span>
<span>期</span>
</div>
<style>
.enter{
display: inline-block;
margin: auto 0.5rem;
font-size: 1.2rem;
text-align: center;
vertical-align: top;
color: #BCAD98;
}
.enter>input{
width: 4rem;
border-top: 1px solid #DDD;
border-bottom: 1px solid #DDD;
box-shadow: 0 1px 1px #DDD inset;
color: #8E8066;
text-align: center;
background-color: transparent;
}
.enter>i{
width: 2rem;
border: 1px solid #DDD;
background-color: #F0F0EE;
background-image: linear-gradient(to bottom, #FFF, #ECECEA);
}
.enter>i:active{
background-color: #EFEFED;
background-image: linear-gradient(to bottom, #EFEFED, #E8E8E6);
}
.enter>input, .enter>i{
display: inline-block;
height: 1.8rem;
line-height: 1.8rem;
vertical-align: middle;
}
</style>