[移动端]移动端上遇到的各种坑与相对解决方式
Posted yxysuanfa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[移动端]移动端上遇到的各种坑与相对解决方式相关的知识,希望对你有一定的参考价值。
mobileHack
这里收集了很多移动端上遇到的各种坑与相对解决方式
1.问题:手机端 click 事件会有大约 300ms 的延迟
原因:手机端事件 touchstart –> touchmove –> touchend or touchcancel –> click。由于在touch事件触发之后,浏览器要推断用户是否会做出双击屏幕的操作,所以会等待300ms来推断,再做出是否触发click事件的处理。所以就会有300ms的延迟
解决方法:使用touch事件来取代click事件。如 zepto.js 的tap事件和fastClick,还有我自己也写了个移动端手势操作库mTouch。都有对应的事件能够取代click事件解决问题
2.问题:在部分机型下(如小米4、小米2s、中兴) body 设置的 font-size 是用 rem 单位的话,若其它元素没有设置font-size,该font-size值继承于body,则会非常高概率出现字体异常变大的情况
原因:预计是跟app的webview默认设置有关。body的font-size使用rem单位,就是相对于当前根节点的font-size来确定的,可能在某些webview的设置下。body用的是webview设置的默认字体大小。由于在我给html设置了一个px单位的默认font-size时,还是会出现字体异常变大的情况,具体webview的一些细节就没有再研究了
解决方法:body设置一个px单位的默认font-size值,不用rem,或者给字体会异常变大的元素设定一个px单位的font-size值
3.问题:使用zepto的 tap 事件时会出现“点透”bug,比方:一个元素A绑定了tap事件,紧跟其后的元素B绑定了click事件,A触发tap事件时将自己remove掉。B就会自己主动“掉”到A的位置。接下来就是不正常的情况,由于这个时候B的click事件也触发了
原因:由于tap事件是通过 touchstart 、touchmove 、 touchend 这三个事件来模拟实现的,在手机端事件机制中,触发touch事件后会紧接着触发touch事件坐标元素的click事件。由于B元素在300ms内刚好“掉”回来A的位置。所以就触发了B的click事件。还有zepto的tap事件都是代理到body的,所以想通过e.preventDefault()阻止默认行为也是不可行的
解决方法:(1)A元素换成click事件。(2)使用我写的库 mTouch 来给A绑定tap事件。然后在事件回调中通过e.preventDefault()来阻止默认行为,或者换用其它的支持tap事件的库
问题、4.动画
动画有非常多种,比方側边栏菜单的滑入滑出、元素的响应动画、页面切换之间的过场等等,在H5之下的众多实现方法都没有办法达到纯原生的性能。一般这些的话有几种不同的选择:css3动画。javascript动画,原生动画。css3动画非常的消耗性能,假设某一个元素用到css3动画可能还看不出来。但大面积或过场使用css3动画会让app低端手机体验非常差。最好的选择通常是通过框架调用底层的动画,但无论怎么样等于在原来的代码上包上了一层,性能还是不可避免的受到影响。比方在一个新页面的载入上,假设调用底层动画要考虑的问题有两个。一个是本身资源页面的渲染问题,另一个是远程数据的获取。即便是这些动画能够非常快的响应,但大量的css页面会导致渲染卡顿,滑入时可能会有白屏/机器卡顿的现象。为了解决这些性能问题又必须要用到预载入或模拟动画。即便是这样,滑入滑出的动画在低端的安卓机器上还是有非常多问题,假设获取服务端数据处理的方式不合适,卡顿白屏的现象会更严重。具体看下面的数据获取方式。
问题、5.获取服务端数据
首先要接受的是。这里的数据获取都是在资源页面上异步完毕的,由于仅仅有这样才干让这些资源页面完毕预载入或者渲染。
可是异步拿到的数据在填入页面中时可能会涉及DOM操作。众所周知,DOM操作非常消耗性能,假设页面小还好,页面稍大数据略微复杂一点。频繁的DOM操作会导致明显的闪白。而且最重要的一点是。假设页面载入进来之后数据更新的速度太慢。也会让页面模板等待非常长时间,对用户体验又不友好,总不能每次打开都像浏览器一样等待刷新是吧。这个问题假设没有得到解决。H5APP是非常难承担大规模数据的页面,在它们之中频繁切换更是难上加难,那么肯定有人也会想到用MVVM的方式,事实上我也写过一些基于MVVM的H5APP。相对来说它们获取数据和更新数据的方式更敏捷更科学。但写的过程中又要注意非常多H5独有的问题,这些问题在下面的页面切换里来讲。
一些实用技能点
通过设置css属性 -webkit-tap-highlight-color: rgba(0, 0, 0, 0);取消掉手机端webkit浏览器 点击button或超链接之类的 默认灰色背景色
设置css属性 -webkit-user-select:none; 控制用户不可选择文字
区域性 overflow: scroll | auto 滚动时使用原生效果:-webkit-overflow-scrolling: touch (ios8+。android4.0+)
工具类站点
iphone6的那些事
响应式測试工具
Firefox 浏览器内置了 自己定义设计视图
的功能。能够通过 Firefox->Web 开发人员->自己定义设计视图
(或者摁下 Shift + Ctrl + m
)。相比网络工具,运行更加流畅,无需联网。
推断 iPad 和 iPhone 的版本号和状态的 CSS 媒体查询代码
https://quirktools.com/screenfly/
媒体查询经常使用样式表:
<link rel="stylesheet" media="all and (orientation:portrait)" href="portrait.css"> // 竖放载入
<link rel="stylesheet" media="all and (orientation:landscape)"href="landscape.css"> // 横放载入
竖屏时使用的样式
<style media="all and (orientation:portrait)" type="text/css">
#landscape { display: none; }
</style>
//横屏时使用的样式
<style media="all and (orientation:landscape)" type="text/css">
#portrait { display: none; }
</style>
Web app 开发的最佳实践与中文总结
It’s not a web app. It’s an app you install from the web.
来自maxzhang的一些移动端经验总结干货
移动Web开发。4行代码检測浏览器是否支持position:fixed
移动Web开发实践——解决position:fixed自适应BUG
本资料非常多引用了指尖上的js系列
指尖下的js ——多触式web前端开发之中的一个:对于Touch的处理
基础知识
meta标签
meta标签大全 http://segmentfault.com/blog/ciaocc/1190000002407912
meta标签。这些meta标签在开发webapp时起到非常关键的数据
<meta content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0" name="viewport" />
<meta content="yes" name="apple-mobile-web-app-capable" />
<meta content="black" name="apple-mobile-web-app-status-bar-style" />
<meta content="telephone=no" name="format-detection" />
第一个meta标签表示:强制让文档的宽度与设备的宽度保持1:1。而且文档最大的宽度比例是1.0,且不同意用户点击屏幕放大浏览;
尤其要注意的是content里多个属性的设置一定要用分号+空格来隔开,假设不规范将不会起作用。
注意依据 public_00 提供的资料补充,content 使用分号作为分隔,在老的浏览器是支持的。但不是规范写法。
规范的写法应该是使用逗号分隔,參考 Safari HTML Reference - Supported Meta Tags 和 Android - Supporting Different Screens in Web Apps
当中:
- width - viewport的宽度
- height - viewport的高度
- initial-scale - 初始的缩放比例
- minimum-scale - 同意用户缩放到的最小比例
- maximum-scale - 同意用户缩放到的最大比例
- user-scalable - 用户能否够手动缩放
第二个meta标签是iphone设备中的safari私有meta标签,它表示:同意全屏模式浏览;
第三个meta标签也是iphone的私有标签。它指定的iphone中safari顶端的状态条的样式。
第四个meta标签表示:告诉设备忽略将页面中的数字识别为电话号码
在设置了initial-scale=1 之后,我们最终能够以1:1 的比例进行页面设计了。
关于viewport。另一个非常重要的概念是:iphone 的safari 浏览器全然没有滚动栏。而且不是简单的“隐藏滚动栏”,
是根本没有这个功能。iphone 的safari 浏览器实际上从一開始就完整显示了这个网页,然后用viewport 查看当中的一部分。
当你用手指拖动时,事实上拖的不是页面,而是viewport。浏览器行为的改变不止是滚动栏,交互事件也跟普通桌面不一样。
(请參考:指尖的下JS 系列文章)
更具体的 viewport 相关的知识也能够參考
移动开发事件
手势事件
- touchstart //当手指接触屏幕时触发
- touchmove //当已经接触屏幕的手指開始移动后触发
- touchend //当手指离开屏幕时触发
- touchcancel
触摸事件
- gesturestart //当两个手指接触屏幕时触发
- gesturechange //当两个手指接触屏幕后開始移动时触发
- gestureend
屏幕旋转事件
- onorientationchange
检測触摸屏幕的手指何时改变方向
- orientationchange
touch事件支持的相关属性
- touches
- targetTouches
- changedTouches
- clientX // X coordinate of touch relative to the viewport (excludes scroll offset)
- clientY // Y coordinate of touch relative to the viewport (excludes scroll offset)
- screenX // Relative to the screen
- screenY // Relative to the screen
- pageX // Relative to the full page (includes scrolling)
- pageY // Relative to the full page (includes scrolling)
- target // Node the touch event originated from
- identifier // An identifying number, unique to each touch event
- 屏幕旋转事件:onorientationchange
推断屏幕是否旋转
function orientationChange() {
switch(window.orientation) {
case 0:
alert("肖像模式 0,screen-width: " + screen.width + "; screen-height:" + screen.height);
break;
case -90:
alert("左旋 -90,screen-width: " + screen.width + "; screen-height:" + screen.height);
break;
case 90:
alert("右旋 90,screen-width: " + screen.width + "; screen-height:" + screen.height);
break;
case 180:
alert("风景模式 180,screen-width: " + screen.width + "; screen-height:" + screen.height);
break;
};};
addEventListener(\'load\', function(){
orientationChange();
window.onorientationchange = orientationChange;
});
JS 单击延迟
click 事件由于要等待单击确认,会有 300ms 的延迟,体验并非非常好。
开发人员大多数会使用封装的 tap 事件来取代click 事件,所谓的 tap 事件由 touchstart 事件 + touchmove 推断 + touchend 事件封装组成。
Creating Fast Buttons for Mobile Web Applications
Eliminate 300ms delay on click events in mobile Safari
WebKit CSS:
携程 UED 整理的 Webkit CSS 文档 ,全面、方便查询,下面为经常使用属性。
①“盒模型”的具体描写叙述性质的包围盒块内容,包含边界,填充等等。
css
-webkit-border-bottom-left-radius: radius;
-webkit-border-top-left-radius: horizontal_radius vertical_radius;
-webkit-border-radius: radius; //容器圆角
-webkit-box-sizing: sizing_model; 边框常量值:border-box/content-box
-webkit-box-shadow: hoff voff blur color; /*容器阴影(參数分别为:水平X 方向偏移量。垂直Y方向偏移量。高斯模糊半径值;阴影颜色值)*/
-webkit-margin-bottom-collapse: collapse_behavior; /*常量值:collapse/discard/separate*/
-webkit-margin-start: width;
-webkit-padding-start: width;
-webkit-border-image: url(borderimg.gif) 25 25 25 25 round/stretch round/stretch;
-webkit-appearance: push-button; /*内置的CSS 表现,临时仅仅支持push-button*/
②“视觉格式化模型”描写叙述性质,确定了位置和大小的块元素。
direction: rtl
unicode-bidi: bidi-override; 常量:bidi-override/embed/normal
③“视觉效果”描写叙述属性。调整的视觉效果块内容。包含溢出行为。调整行为,能见度,动画,变换。和过渡。
clip: rect(10px, 5px, 10px, 5px)
resize: auto; 常量:auto/both/horizontal/none/vertical
visibility: visible; 常量: collapse/hidden/visible
-webkit-transition: opacity 1s linear; 动画效果 ease/linear/ease-in/ease-out/ease-in-out
-webkit-backface-visibility: visibler; 常量:visible(默认值)/hidden
-webkit-box-reflect: right 1px; 镜向反转
-webkit-box-reflect: below 4px -webkit-gradient(linear, left top, left bottom,
from(transparent), color-stop(0.5, transparent), to(white));
-webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0)));; //CSS 遮罩/蒙板效果
-webkit-mask-attachment: fixed; 常量:fixed/scroll
-webkit-perspective: value; 常量:none(默认)
-webkit-perspective-origin: left top;
-webkit-transform: rotate(5deg);
-webkit-transform-style: preserve-3d; 常量:flat/preserve-3d; (2D 与3D)
④“生成的内容,自己主动编号。并列出”描写叙述属性,同意您更改内容的一个组成部分。创建自己主动编号的章节和标题。和操纵的风格清单的内容。
content: “Item” counter(section) ” “;
This resets the counter.
First section
>two section
three section
counter-increment: section 1;
counter-reset: section;
⑤“分页媒体”描写叙述性能与外观的属性。控制印刷版本号的网页,如分页符的行为。
page-break-after: auto; 常量:always/auto/avoid/left/right
page-break-before: auto; 常量:always/auto/avoid/left/right
page-break-inside: auto; 常量:auto/avoid
⑥“颜色和背景”描写叙述属性控制背景下的块级元素和颜色的文本内容的组成部分。
-webkit-background-clip: content; 常量:border/content/padding/text
-webkit-background-origin: padding; 常量:border/content/padding/text
-webkit-background-size: 55px; 常量:length/length_x/length_y
⑦ “字型”的具体描写叙述性质的文字字体的选择范围内的一个因素。
报告还描写叙述属性用于下载字体定义。
unicode-range: U+00-FF, U+980-9FF;
⑧“文本”描写叙述属性的特定文字样式,间距和自己主动滚屏。
text-shadow: #00FFFC 10px 10px 5px;
text-transform: capitalize; 常量:capitalize/lowercase/none/uppercase
word-wrap: break-word; 常量:break-word/normal
-webkit-marquee: right large infinite normal 10s; 常量:direction(方向) increment(迭代次数) repetition(反复) style(样式) speed(速度);
-webkit-marquee-direction: ahead/auto/backwards/down/forwards/left/reverse/right/up
-webkit-marquee-incrementt: 1-n/infinite(无穷次)
-webkit-marquee-speed: fast/normal/slow
-webkit-marquee-style: alternate/none/scroll/slide
-webkit-text-fill-color: #ff6600; 常量:capitalize, lowercase, none, uppercase
-webkit-text-security: circle; 常量:circle/disc/none/square
-webkit-text-size-adjust: none; 常量:auto/none;
-webkit-text-stroke: 15px #fff;
-webkit-line-break: after-white-space; 常量:normal/after-white-space
-webkit-appearance: caps-lock-indicator;
-webkit-nbsp-mode: space; 常量: normal/space
-webkit-rtl-ordering: logical; 常量:visual/logical
-webkit-user-drag: element; 常量:element/auto/none
-webkit-user-modify: read- only; 常量:read-write-plaintext-only/read-write/read-only
-webkit-user-select: text; 常量:text/auto/none
⑨“表格”描写叙述的布局和设计性能表的具体内容。
-webkit-border-horizontal-spacing: 2px;
-webkit-border-vertical-spacing: 2px;
-webkit-column-break-after: right; 常量:always/auto/avoid/left/right
-webkit-column-break-before: right; 常量:always/auto/avoid/left/right
–webkit-column-break-inside: logical; 常量:avoid/auto
-webkit-column-count: 3; //分栏
-webkit-column-rule: 1px solid #fff;
style:dashed,dotted,double,groove,hidden,inset,none,outset,ridge,solid
⑩“用户界面”描写叙述属性,涉及到用户界面元素在浏览器中,如滚动文字区。滚动栏,等等。报告还描写叙述属性,范围以外的网页内容,如光标的标注样式和显示当您按住触摸触摸
目标,如在iPhone上的链接。
-webkit-box-align: baseline,center,end,start,stretch 常量:baseline/center/end/start/stretch
-webkit-box-direction: normal;常量:normal/reverse
-webkit-box-flex: flex_valuet
-webkit-box-flex-group: group_number
-webkit-box-lines: multiple; 常量:multiple/single
-webkit-box-ordinal-group: group_number
-webkit-box-orient: block-axis; 常量:block-axis/horizontal/inline-axis/vertical/orientation
–webkit-box-pack: alignment; 常量:center/end/justify/start
动画过渡
这是 Webkit 中最具创新力的特性:使用过渡函数定义动画。
-webkit-animation: title infinite ease-in-out 3s;
animation 有这几个属性:
-webkit-animation-name: //属性名。就是我们定义的keyframes
-webkit-animation-duration:3s //持续时间
-webkit-animation-timing-function: //过渡类型:ease/ linear(线性) /ease-in(慢到快)/ease-out(快到慢) /ease-in-out(慢到快再到慢) /cubic-bezier
-webkit-animation-delay:10ms //动画延迟(默认0)
-webkit-animation-iteration-count: //循环次数(默认1)。infinite 为无限
-webkit-animation-direction: //动画方式:normal(默认 正向播放); alternate(交替方向。第偶数次正向播放,第奇数次反向播放)
这些相同是能够简写的。
但真正让我觉的非常爽的是keyframes。它能定义一个动画的转变过程供调用,过程为0%到100%或from(0%)到to(100%)。
简单点说。仅仅要你有想法,你想让元素在这个过程中以什么样的方式改变都是非常easy的。
-webkit-transform: 类型(缩放scale/旋转rotate/倾斜skew/位移translate)
scale(num,num) 放大倍率。scaleX 和 scaleY(3),能够简写为:scale(* , *)
rotate(*deg) 转动角度。rotateX 和 rotateY,能够简写为:rotate(* , *)
Skew(*deg) 倾斜角度。skewX 和skewY,可简写为:skew(* , *)
translate(*,*) 坐标移动。translateX 和translateY,可简写为:translate(* , *)。
页面描写叙述
<link rel="apple-touch-icon-precomposed" href="http://www.xxx.com/App_icon_114.png" />
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://www.xxx.com/App_icon_72.png" />
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://www.xxx.com/App_icon_114.png" />
这个属性是当用户把连接保存到手机桌面时使用的图标,假设不设置。则会用网页的截图。有了这,就能够让你的网页像APP一样存在手机里了
<link rel="apple-touch-startup-image" href="/img/startup.png" />
这个是APP启动画面图片。用途和上面的相似,假设不设置,启动画面就是白屏,图片像素就是手机全屏的像素
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
这个描写叙述是表示打开的web app的最上面的时间、信号栏是黑色的,当然也能够设置其它參数,具体參数说明请參照:Safari HTML Reference - Supported Meta Tags
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
常见的 iPhone 和 Android 屏幕參数。
- 设备 分辨率 设备像素比率
- Android LDPI 320×240 0.75
- Iphone 3 & Android MDPI 320×480 1
- Android HDPI 480×800 1.5
- Iphone 4 960×640 2.0
iPhone 4的一个 CSS 像素实际上表现为一块 2×2 的像素。所以图片像是被放大2倍一样,模糊不清楚。
解决的方法:
1、页面引用
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" />
<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 2.0)" href="retina.css" />
2、CSS文件中
#header {
background:url(mdpi/bg.png);
}
@media screen and (-webkit-device-pixel-ratio: 1.5) {
/*CSS for high-density screens*/
#header {
background:url(hdpi/bg.png);
}
}
移动 Web 开发经验技巧
点击与click事件
对于a标记的点击导航,默认是在onclick事件中处理的。而移动client对onclick的响应相比PC浏览器有着明显的几百毫秒延迟。
在移动浏览器中对触摸事件的响应顺序应当是:
ontouchstart -> ontouchmove -> ontouchend -> onclick
因此,假设确实要加快对点击事件的响应。就应当绑定ontouchend事件。
使用click会出现绑定点击区域闪一下的情况,解决:给该元素一个样式例如以下
-webkit-tap-highlight-color: rgba(0,0,0,0);
假设不使用click,也不能简单的用touchstart或touchend替代,须要用touchstart的模拟一个click事件,而且不能发生touchmove事件。或者用zepto中的tap(轻击)事件。
body
{
-webkit-overflow-scrolling: touch;
}
用iphone或ipad浏览非常长的网页滚动时的滑动效果非常不错吧?只是假设是一个div,然后设置 height:200px;overflow:auto;
的话。能够滚动可是全然没有那滑动效果,非常郁闷吧?
我看到非常多站点为了实现这一效果,用了第三方类库,最经常使用的是iscroll(包含新浪手机页。百度等)
我一開始也使用,只是自从用了-webkit-overflow-scrolling: touch;
样式后,就全然能够抛弃第三方类库了,把它加在body{}区域,全部的overflow须要滚动的都能够生效了。
另外有一篇比較全的移动端点击解决方式 http://www.zhihu.com/question/28979857
锁定 viewport
ontouchmove="event.preventDefault()" //锁定viewport,不论什么屏幕操作不移动用户界面(弹出键盘除外)。
利用 Media Query监听
Media Query 相信大部分人已经使用过了。事实上 JavaScript能够配合 Media Query这么用:
var mql = window.matchMedia("(orientation: portrait)");
mql.addListener(handleOrientationChange);
handleOrientationChange(mql);
function handleOrientationChange(mql) {
if (mql.matches) {
alert(\'The device is currently in portrait orientation \')
} else {
alert(\'The device is currently in landscape orientation\')
}}
借助了 Media Query 接口做的事件监听,所以非常强大!
也能够通过获取 CSS 值来使用 Media Query 推断设备情况,详情请看:JavaScript 依据 CSS Media Queries 推断设备的方法。
rem最佳实践
rem是非常好用的一个属性,能够依据html来设定基准值,而且兼容性也非常不错。只是有的时候还是须要对一些莫名其妙的浏览器优雅降级。下面是两个实践
- http://jsbin.com/vaqexuge/4/edit 这有个demo,发现chrome当font-size小于12时。rem会依照12来计算。因此设置基准值要考虑这一点
能够用下面的代码片段保证在低端浏览器下也不会出问题
html { font-size: 62.5%; }
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1 { font-size: 24px; font-size: 2.4rem; } /* =24px */
被点击元素的外观变化。能够使用样式来设定:
-webkit-tap-highlight-color: 颜色
检測推断 iPhone/iPod
开发特定设备的移动站点。首先要做的就是设备侦測了。
下面是使用Javascript侦測iPhone/iPod的UA,然后转向到专属的URL。
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {
if (document.cookie.indexOf("iphone_redirect=false") == -1) {
window.location = "http://m.example.com";
}
}
尽管Javascript是能够在水果设备上运行的,可是用户还是能够禁用。它也会造成client刷新和额外的传输数据,所下面面是服务器端侦測和转向:
if(strstr($_SERVER[\'HTTP_USER_AGENT\'],\'iPhone\') || strstr($_SERVER[\'HTTP_USER_AGENT\'],\'iPod\')) {
header(\'Location: http://yoursite.com/iphone\');
exit();
}
阻止旋转屏幕时自己主动调整字体大小
html, body, form, fieldset, p, div, h1, h2, h3, h4, h5, h6 {-webkit-text-size-adjust:none;}
模拟:hover伪类
由于iPhone并没有鼠标指针,所以没有hover事件。那么CSS :hover伪类就没用了。可是iPhone有Touch事件,onTouchStart 相似 onMouseOver,onTouchEnd 相似 onMouseOut。所以我们能够用它来模拟hover。使用Javascript:
var myLinks = document.getElementsByTagName(\'a\');
for(var i = 0; i < myLinks.length; i++){
myLinks[i].addEventListener(’touchstart’, function(){this.className = “hover”;}, false);
myLinks[i].addEventListener(’touchend’, function(){this.className = “”;}, false);
}
然后用CSS添加hover效果:
a:hover, a.hover { /* 你的hover效果 */ }
这样设计一个链接,感觉能够更像button。
而且,这个模拟能够用在不论什么元素上。
Flexbox 布局
http://www.w3.org/TR/css3-flexbox/
居中问题
居中是移动端跟pc端共同的噩梦。这里有两种兼容性比較好的新方案。
table布局法
.box{
text-align:center;
display:table-cell;
vertical-align:middle;
}老版本号flex布局法
.box{
display:-webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
text-align:center;
}
以上两种事实上各自是retchat跟ionic的布局基石。
这里有更具体的很多其它的选择http://www.zhouwenbin.com/%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E6%B3%95/ 来自周文彬的博客
移动端实现标题文字截断
http://www.75team.com/archives/611
处理 Retina 双倍屏幕
(经典)Using CSS Sprites to optimize your website for Retina Displays
使用CSS3的background-size优化苹果的Retina屏幕的图像显示
使用 CSS sprites 来优化你的站点在 Retina 屏幕下显示
(案例)CSS IMAGE SPRITES FOR RETINA (HIRES) DEVICES
input类型为date情况下不支持placeholder(来自于江水)
这事实上是浏览器自己的处理。
由于浏览器会针对此类型 input 添加 datepicker 模块。
对 input type date 使用 placeholder 的目的是为了让用户更准确的输入日期格式。iOS 上会有 datepicker 不会显示 placeholder 文字。可是为了统一表单外观,往往须要显示。
Android 部分机型没有 datepicker 也不会显示 placeholder 文字。
桌面端(Mac)
- Safari 不支持 datepicker,placeholder 正常显示。
- Firefox 不支持 datepicker,placeholder 正常显示。
- Chrome 支持 datepicker,显示 年、月、日 格式,忽略 placeholder。
移动端
- iPhone5 iOS7 有 datepicker 功能,可是不显示 placeholder。
- Andorid 4.0.4 无 datepicker 功能。不显示 placeholder
解决方法:
<input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type=\'date\')" id="date">
由于text是支持placeholder的。
因此当用户focus的时候自己主动把type类型改变为date,这样既有placeholder也有datepicker了
推断照片的横竖排列
有这样一种需求,须要推断用户照片是横着拍出来的还是竖着拍出来的,这里须要使用照片得exif信息:
$("input").change(function() {
var file = this.files[0];
fr = new FileReader;
fr.onloadend = function() {
var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));
alert(exif.Orientation);
};
fr.readAsBinaryString(file);
});
能够使用这两个库 来取exif信息http://www.nihilogic.dk/labs/binaryajax/binaryajax.js http://www.nihilogic.dk/labs/exif/exif.js
Android上当viewport的width大于device-width时出现文字无故折行的解决的方法
http://www.iunbug.com/archives/2013/04/23/798.html
白屏解决与优化方案
当前非常多无线页面都使用前端模板进行数据渲染。那么在糟糕的网速情况下,一进去页面,看到的不是白屏就是 loading,这成为白屏问题。
此问题发生的原因基本能够归结为网速跟静态资源
1、css文件载入须要一些时间,在载入的过程中页面是空白的。 解决:能够考虑将css代码前置和内联。
2、首屏无实际的数据内容,等待异步载入数据再渲染页面导致白屏。
解决:在首屏直接同步渲染html,兴许的滚屏等再採用异步请求数据和渲染html。
3、首屏内联js的运行会堵塞页面的渲染。 解决:尽量不在首屏html代码中放置内联脚本。(来自翔歌)
解决方式
根本原因是client渲染的无力,因此最简单的方法是在服务器端,使用模板引擎渲染全部页面。同一时候
1降低文件载入体积,如html压缩。js压缩
2加快js运行速度 比方常见的无限滚动的页面,能够使用js先渲染一个屏幕范围内的东西
3提供一些友好的交互,比方提供一些假的滚动栏
4使用本地存储处理静态文件。
怎样实现打开已安装的app,若未安装则引导用户安装?
来自 http://gallery.kissyui.com/redirectToNative/1.2/guide/index.html kissy mobile
通过iframe src发送请求打开app自己定义url scheme,如taobao://home(淘宝首页) 、etao://scan(一淘扫描));
假设安装了client则会直接唤起,直接唤起后,之前浏览器窗体(或者扫码工具的webview)推入后台;
假设在指定的时间内client没有被唤起,则js重定向到app下载地址。
大概实现代码例如以下
goToNative:function(){
if(!body) {
setTimeout(function(){
doc.body.appendChild(iframe);
}, 0);
} else {
body.appendChild(iframe);
}
setTimeout(function() {
doc.body.removeChild(iframe);
gotoDownload(startTime);//去下载,下载链接通常是itunes app store或者apk文件链接
/**
* 測试时间设置小于800ms时,在android下的UC浏览器会打开native app时并下载apk,
* 測试android+UC下打开native的时间最好大于800ms;
*/
}, 800);
}
须要注意的是 假设是android chrome 25版本号以后。在iframe src不会发送请求。
原因例如以下https://developers.google.com/chrome/mobile/docs/intents 。通过location href使用intent机制拉起client可行而且当前页面不跳转。
window.location = \'intent://\' + schemeUrl + \'#Intent;scheme=\' + scheme + \';package=\' + self.package + \';end\';
补充一个来自三水清的具体解说 http://js8.in/2013/12/16/ios%E4%BD%BF%E7%94%A8schema%E5%8D%8F%E8%AE%AE%E8%B0%83%E8%B5%B7app/
active的兼容(来自薛端阳)
今天发现。要让a链接的CSS active伪类生效,仅仅须要给这个a链接的touch系列的随意事件touchstart/touchend绑定一个空的匿名方法就可以hack成功
<style>
a {
color: #000;
}
a:active {
color: #fff;
}
</style>
<a herf=”asdasd”>asdasd</a>
<script>
var a=document.getElementsByTagName(‘a’);
for(var i=0;i<a.length;i++){
a[i].addEventListener(‘touchstart’,function(){},false);
}
</script>
消除transition闪屏
两个方法:使用css3动画的时尽量利用3D加速,从而使得动画变得流畅。动画过程中的动画闪白能够通过 backface-visibility 隐藏。
-webkit-transform-style: preserve-3d;
/*设置内嵌的元素在 3D 空间怎样呈现:保留 3D*/
-webkit-backface-visibility: hidden;
/*(设置进行转换的元素的背面在面对用户时是否可见:隐藏)*/
測试是否支持svg图片
document.implementation.hasFeature("http:// www.w3.org/TR/SVG11/feature#Image", "1.1")
考虑兼容“隐私模式”(from http://blog.youyo.name/archives/smarty-phones-webapp-deverlop-advance.html)
ios的safari提供一种“隐私模式”,假设你的webapp考虑兼容这个模式,那么在使用html5的本地存储的一种————localStorage时,可能由于“隐私模式”下没有权限读写localstorge而使代码抛出错误。导致兴许的js代码都无法运行了。
既然在safari的“隐私模式”下,没有调用localStorage的权限,首先想到的是先推断是否支持localStorage,代码例如以下:
if(\'localStorage\' in window){
//须要使用localStorage的代码写在这
}else{
//不支持的提示和向下兼容代码
}
測试发现,即使在safari的“隐私模式”下,’localStorage’ in window的返回值依旧为true,也就是说。if代码块内部的代码依旧会运行,问题没有得到解决。
接下来仅仅能相当使用try catch了。尽管这是一个不太推荐被使用的方法,使用try catch捕获错误,使兴许的js代码能够继续运行。代码例如以下:
try{
if(\'localStorage\' in window){
//须要使用localStorage的代码写在这
}else{
//不支持的提示和向下兼容代码
}
}catch(e){
// 隐私模式相关提示代码和不支持的提示和向下兼容代码
}
所以。提醒大家注意,在须要兼容ios的safari的“隐私模式”的情况下,本地存储相关的代码须要使用try catch包裹并降级兼容。
安卓手机点击锁定页面效果问题
有些安卓手机。页面点击时会停止页面的javascript,css3动画等的运行,这个比較蛋疼。
只是能够用阻止默认事件解决。具体见
http://stackoverflow.com/questions/10246305/android-browser-touch-events-stop-display-being-updated-inc-canvas-elements-h
function touchHandlerDummy(e)
{
e.preventDefault();
return false;
}
document.addEventListener("touchstart", touchHandlerDummy, false);
document.addEventListener("touchmove", touchHandlerDummy, false);
document.addEventListener("touchend", touchHandlerDummy, false);
消除ie10里面的那个叉号
input:-ms-clear{display:none;}
关于ios与os端字体的优化(横竖屏会出现字体加粗不一致等)
UIWebView font is thinner in portrait than landscape
推断用户是否是“将网页加入到主屏后,再从主屏幕打开这个网页”的
navigator.standalone
隐藏地址栏 & 处理事件的时候,防止滚动栏出现:
// 隐藏地址栏 & 处理事件的时候 ,防止滚动栏出现
addEventListener(\'load\', function(){
setTimeout(function(){ window.scrollTo(0, 1); }, 100);
});
ios7 能够通过meta标签的minimal来隐藏地址栏了
http://darkblue.sdf.org/weblog/ios-7-dot-1-mobile-safari-minimal-ui.html
推断是否为iPhone:
// 推断是否为 iPhone :
function isAppleMobile() {
return (navigator.platform.indexOf(\'iPhone\') != -1);
};
localStorage:
var v = localStorage.getItem(\'n\') ?
localStorage.getItem(\'n\') : ""; // 假设名称是 n 的数据存在 ,则将其读出 ,赋予变量 v 。 localStorage.setItem(\'n\', v); // 写入名称为 n、值为 v 的数据 localStorage.removeItem(\'n\'); // 删除名称为 n 的数据
使用特殊链接:
假设你关闭自己主动识别后 。又希望某些电话号码能够链接到 iPhone 的拨号功能 。那么能够通过这样来声明电话链接 ,
<a href="tel:12345654321">打电话给我</a>
<a href="sms:12345654321">发短信</a>
或用于单元格:
<td onclick="location.href=\'tel:122\'">
自己主动大写与自己主动修正
要关闭这两项功能。能够通过autocapitalize 与autocorrect 这两个选项:
<input type="text" autocapitalize="off" autocorrect="off" />
不让 Android 识别邮箱
<meta content="email=no" name="format-detection" />
禁止 iOS 弹出各种操作窗体
-webkit-touch-callout:none
禁止用户选中文字
-webkit-user-select:none
动画效果中,使用 translate 比使用定位性能高
Why Moving Elements With Translate() Is Better Than Pos:abs Top/left
拿到滚动栏
window.scrollY
window.scrollX
比方要绑定一个touchmove的事件。正常的情况下相似这样(来自呼吸二氧化碳)
$(\'div\').on(\'touchmove\', function(){
//.….code
{});
而假设中间的code须要处理的东西多的话,fps就会下降影响程序顺滑度,而假设改成这样
$(\'div\').on(\'touchmove\', function(){
setTimeout(function(){
//.….code
},0);
{});
把代码放在setTimeout中。会发现程序变快.
关于 iOS 系统中。Web APP 启动图片在不同设备上的适应性设置
position:sticky与position:fixed布局
http://www.zhouwenbin.com/positionsticky-%E7%B2%98%E6%80%A7%E5%B8%83%E5%B1%80/
http://www.zhouwenbin.com/sticky%E6%A8%A1%E6%8B%9F%E9%97%AE%E9%A2%98/
关于 iOS 系统中,中文输入法输入英文时,字母之间可能会出现一个六分之中的一个空格
能够通过正则去掉
this.value = this.value.replace(/\\u2006/g, \'\');
关于android webview中,input元素输入时出现的怪异情况
见下图
Android Web 视图,至少在 HTC EVO 和三星的 Galaxy Nexus 中。文本输入框在输入时表现的就像占位符。情况为一个相似水印的东西在用户输入区域。一旦用户開始输入便会消失(见图片)。
在 Android 的默认样式下当输入框获得焦点后,若存在一个绝对定位或者 fixed 的元素。布局会被破坏,其它元素与系统输入字段会发生重叠(如搜索图标将消失为搜索字段)。能够观察到布局与原始输入字段有偏差(见截图)。
这是一个相当复杂的问题,下面简单布局能够重现这个问题:
<label for="phone">Phone: *</label>
<input type="tel" name="phone" id="phone" minlength="10" maxlength="10" inputmode="latin digits" required="required" />
解决方法
-webkit-user-modify: read-write-plaintext-only
具体參考http://www.bielousov.com/2012/android-label-text-appears-in-input-field-as-a-placeholder/
注意,该属性会导致中文不能输入词组,仅仅能单个字。感谢鬼哥与飞(游勇飞)贡献此问题与解决方式
另外,在position:fixed后的元素里,尽量不要使用输入框。很多其它的bug可參考
http://www.cosdiv.com/page/M0/S882/882353.html
依旧无法解决(摩托罗拉ME863手机),则使用input:text类型而非password类型,并设置其设置 -webkit-text-security: disc; 隐藏输入密码从而解决。
JS动态生成的select下拉菜单在Android2.x版本号的默认浏览器里不起作用
解决方法删除了overflow-x:hidden; 然后在JS生成下来菜单之后focus聚焦,这两步操作之后攻克了问题。
(来自岛都-小Qi)
Andriod 上去掉语音输入button
input::-webkit-input-speech-button {display: none}
IE10 的特殊鼠标事件
iOS 输入框最佳实践
Mobile-friendly input of a digits + spaces string (a credit card number)
HTML5 input type number vs tel
iPhone: numeric keyboard for text input
Text Programming Guide for iOS - Managing the Keyboard
HTML5 inputs and attribute support
往返缓存问题
点击浏览器的回退,有时候不会自己主动运行js。特别是在mobilesafari中。
这与往返缓存(bfcache)有关系。
有非常多hack的处理方法。能够參考
http://stackoverflow.com/questions/24046/the-safari-back-button-problem
http://stackoverflow.com/questions/11979156/mobile-safari-back-button
不暂停的计时器(safari的进程冻结)
https://www.imququ.com/post/ios-none-freeze-timer.html
或者能够用postmessage方式:
主页面:
// 解决ios safari tab在后台会遭遇进程冻结问题
// http://www.apple.com/safari/#gallery-icloud-tabs
// Safari takes advantage of power-saving technologies such as App Nap, which puts background Safari tabs into a low-power state until you start using them again. In addition, Safari Power Saver conserves battery life by intelligently pausing web videos and other plug‑in content when they’re not front and center on the web pages you visit. All told, Safari on OS X Mavericks lets you browse up to an hour longer than with Chrome or Firefox.1
var work;
function startWorker() {
if (typeof(Worker) !== "undefined") {
if (typeof(work) == "undefined") {
work = new Worker("/workers.js");
}
work.onmessage = function(event) {
// document.getElementById("result-count").innerHTML = event.data.count;
// document.getElementById("result-url").innerHTML = event.data.targetURL;
if (target && event.data.targetURL != "") target.location.href = event.data.targetURL;
};
} else {
console.log(\'does not support Web Workers...\');
}
}
function stopWorker() {
work.terminate();
}
startWorker();
worker:
// 解决ios safari tab在后台会遭遇进程冻结问题
// http://www.apple.com/safari/#gallery-icloud-tabs
// Safari takes advantage of power-saving technologies such as App Nap, which puts background Safari tabs into a low-power state until you start using them again. In addition, Safari Power Saver conserves battery life by intelligently pausing web videos and other plug‑in content when they’re not front and center on the web pages you visit. All told, Safari on OS X Mavericks lets you browse up to an hour longer than with Chrome or Firefox.1
importScripts(\'/socket.io/socket.io.js\');
var count = 0,
targetURL = \'\'
;
var socket = io.connect(\'/\');
socket.on(\'navigate\', function (data) {
count = count++;
postMessage({targetURL:data.url,count:count});
});
Web移动端Fixed布局的解决方式
http://efe.baidu.com/blog/mobile-fixed-layout/
ios上background-attachment:fixed不能正常工作
參考 http://stackoverflow.com/questions/20443574/fixed-background-image-with-ios7
怎样让音频跟视频在ios跟android上自己主动播放
<audio autoplay ><source src="audio/alarm1.mp3" type="audio/mpeg"></audio>
系统默认情况下 audio的autoplay属性是无法生效的,这也是手机为节省用户流量做的考虑。
假设必须要自己主动播放。有两种方式能够解决。
1.捕捉一次用户输入后,让音频载入,下次就可以播放。
//play and pause it once
document以上是关于[移动端]移动端上遇到的各种坑与相对解决方式的主要内容,如果未能解决你的问题,请参考以下文章