Web app 开发的最佳实践与中文总结

本文由清尘发表于2015-05-15 11:34属于移动前端分类

响应式测试工具

Firefox 浏览器内置了 自定义设计视图 的功能,可以通过 Firefox->Web 开发者->自定义设计视图(或者摁下 Shift + Ctrl + m )。相比网络工具,运行更加流畅,无需联网。

媒体查询常用样式表:

<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>

只用硬件加速的 CSS 3 属性做动画效果。只使用 translate3d 系属性,而且使用 transition 时也不可以应用到没有硬件加速的属性上。

不要自己实现滚动条。使用 -webkit-overflow-scrolling: touch 而不是采用类似 iScroll 这样的东西。(可能对 Mobile Web App 更适用。桌面 Web App 使用大数据的动态列表还是用 iScroll 这样的实现吧,效果比原生滚动强不是一点半点。)

在 Chrome Dev Tools 里打开 Show paint rectangles 和 Show composited layer borders 选项就能直观地看到浏览器是怎么渲染你的 Web App 的。对于观察硬件加速的优化效果来说很有帮助。

基础知识

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 使用分号作为分隔,在老的浏览器是支持的,但不是规范写法。

规范的写法应该是使用逗号分隔

其中:

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。浏览器行为的改变不止是滚动条,交互事件也跟普通桌面不一样。

移动开发事件

手势事件

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;
});

双手指滑动事件:

// 双手指滑动事件
addEventListener('load',  function(){ window.onmousewheel = twoFingerScroll;},
    false              // 兼容各浏览器,表示在冒泡阶段调用事件处理程序 (true 捕获阶段)
);
function twoFingerScroll(ev) {
    var delta =ev.wheelDelta/120;              //对 delta 值进行判断(比如正负) ,而后执行相应操作
    return true;
};

JS 单击延迟

click 事件因为要等待单击确认,会有 300ms 的延迟,体验并不是很好。

开发者大多数会使用封装的 tap 事件来代替click 事件,所谓的 tap 事件由 touchstart 事件 + touchmove 判断 + touchend 事件封装组成。

WebKit 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%)。简单点说,只要你有想法,你想让元素在这个过程中以什么样的方式改变都是很简单的。

-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的最上面的时间、信号栏是黑色的,当然也可以设置其它参数

<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事件中处理的。而移动客户端对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 判断设备情况

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是可以在水果设备上运行的,但是用户还是可以禁用。它也会造成客户端刷新和额外的数据传输,所以下面是服务器端侦测和转向:

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效果 */ }

这样设计一个链接,感觉可以更像按钮。并且,这个模拟可以用在任何元素上。

居中问题

居中是移动端跟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的布局基石。

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

白屏解决与优化方案

当前很多无线页面都使用前端模板进行数据渲染,那么在糟糕的网速情况下,一进去页面,看到的不是白屏就是 loading,这成为白屏问题。

此问题发生的原因基本可以归结为网速跟静态资源

1、css文件加载需要一些时间,在加载的过程中页面是空白的。 解决:可以考虑将css代码前置和内联。 2、首屏无实际的数据内容,等待异步加载数据再渲染页面导致白屏。 解决:在首屏直接同步渲染html,后续的滚屏等再采用异步请求数据和渲染html。 3、首屏内联js的执行会阻塞页面的渲染。 解决:尽量不在首屏html代码中放置内联脚本。(来自翔歌)

解决方案

根本原因是客户端渲染的无力,因此最简单的方法是在服务器端,使用模板引擎渲染所有页面。同时

1减少文件加载体积,如html压缩,js压缩 2加快js执行速度 比如常见的无限滚动的页面,可以使用js先渲染一个屏幕范围内的东西 3提供一些友好的交互,比如提供一些假的滚动条 4使用本地存储处理静态文件。

如何实现打开已安装的app,若未安装则引导用户安装?

通过iframe src发送请求打开app自定义url scheme,如taobao://home(淘宝首页) 、etao://scan(一淘扫描)); 如果安装了客户端则会直接唤起,直接唤起后,之前浏览器窗口(或者扫码工具的webview)推入后台; 如果在指定的时间内客户端没有被唤起,则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机制拉起客户端可行并且当前页面不跳转。

window.location = 'intent://' + schemeUrl + '#Intent;scheme=' + scheme + ';package=' + self.package + ';end';

active的兼容

今天发现,要让a链接的CSS active伪类生效,只需要给这个a链接的touch系列的任意事件touchstart/touchend绑定一个空的匿名方法即可hack成功

a {
color: #000;
}
a:active {
color: #fff;
}
<a herf="asdasd">asdasd</a>
var a=document.getElementsByTagName(‘a’);
for(var i=0;i<a.length;i++){
a[i].addEventListener(‘touchstart’,function(){},false);
}

消除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")

安卓手机点击锁定页面效果问题

有些安卓手机,页面点击时会停止页面的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);

判断用户是否是“将网页添加到主屏后,再从主屏幕打开这个网页”的

navigator.standalone

隐藏地址栏 & 处理事件的时候,防止滚动条出现:

// 隐藏地址栏  & 处理事件的时候 ,防止滚动条出现
addEventListener('load', function(){
        setTimeout(function(){ window.scrollTo(0, 1); }, 100);
});

使用特殊链接:

如果你关闭自动识别后 ,又希望某些电话号码能够链接到 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 比使用定位性能高

拿到滚动条

window.scrollY
window.scrollX

比如要绑定一个touchmove的事件,正常的情况下类似这样

$('div').on('touchmove', function(){
//.….code
{});

而如果中间的code需要处理的东西多的话,fps就会下降影响程序顺滑度,而如果改成这样

$('div').on('touchmove', function(){
setTimeout(function(){
//.….code
},0);
{});

把代码放在setTimeout中,会发现程序变快.

JS动态生成的select下拉菜单在Android2.x版本的默认浏览器里不起作用

解决方法删除了overflow-x:hidden; 然后在JS生成下来菜单之后focus聚焦,这两步操作之后解决了问题。

Andriod 上去掉语音输入按钮

input::-webkit-input-speech-button {display: none}

如何让音频跟视频在ios跟android上自动播放

<audio autoplay ><source  src="audio/alarm1.mp3" type="audio/mpeg"></audio>

系统默认情况下 audio的autoplay属性是无法生效的,这也是手机为节省用户流量做的考虑。 如果必须要自动播放,有两种方式可以解决。

1.捕捉一次用户输入后,让音频加载,下次即可播放。

//play and pause it once
document.addEventListener('touchstart', function () {
    document.getElementsByTagName('audio')[0].play();
    document.getElementsByTagName('audio')[0].pause();
});

这种方法需要捕获一次用户的点击事件来促使音频跟视频加载。当加载后,你就可以用javascript控制音频的播放了,如调用audio.play()

2.利用iframe加载资源

var ifr=document.createElement("iframe");
ifr.setAttribute('src', "http://mysite.com/myvideo.mp4");
ifr.setAttribute('width', '1px');
ifr.setAttribute('height', '1px');
ifr.setAttribute('scrolling', 'no');
ifr.style.border="0px";
document.body.appendChild(ifr);

这种方式其实跟第一种原理是一样的。当资源加载了你就可以控制播放了,但是这里使用iframe来加载,相当于直接触发资源加载。 注意,使用创建audio标签并让其加载的方式是不可行的。 慎用这种方法,会对用户造成很糟糕的影响。。

iOS 6 跟 iPhone 5 的那些事

IP5 的媒体查询

@media (device-height: 568px) and (-webkit-min-device-pixel-ratio: 2) {

/* iPhone 5 or iPod Touch 5th generation */

}

使用媒体查询,提供不同的启动图片:

<link href="startup-568h.png" rel="apple-touch-startup-image" media="(device-height: 568px)">
<link href="startup.png" rel="apple-touch-startup-image" sizes="640x920" media="(device-height: 480px)">

拍照上传

<input type=file accept="video/*">
<input type=file accept="image/*">

不支持其他类型的文件 ,如音频,Pages文档或PDF文件。 也没有getUserMedia摄像头的实时流媒体支持。

Cache开启和设置

browser.getSettings().setAppCacheEnabled(true);
browser.getSettings().setAppCachePath("/data/data/[com.packagename]/cache");
browser.getSettings().setAppCacheMaxSize(5*1024*1024); // 5MB

浏览器自带缩放按钮取消显示

browser.getSettings().setBuiltInZoomControls(false);

几个比较好的实践

使用localstorage缓存html

使用lazyload,还要记得lazyload占位图虽然小,但是最好能提前加载到缓存

延时加载执行js

主要原因就在于Android Webview的onPageFinished事件,Android端一般是用这个事件来标识页面加载完成并显示的,也就是说在此之前,会一直loading,但是Android的OnPageFinished事件会在Javascript脚本执行完成之后才会触发。如果在页面中使用JQuery,会在处理完DOM对象,执行完$(document).ready(function() {});事件自会后才会渲染并显示页面。