-
Web App 建议用的样式
用于覆盖 WebView 默认的样式,使得 App 看起来更像原生的 App,——“不露出马脚”
/*
document.documentElement.style.webkitTouchCallout ='none'; //禁止弹出菜单
document.documentElement.style.webkitUserSelect = 'none';//禁止选中
*/
body{
-webkit-text-size-adjust:none; /* 字型大小是不會變的,而使用者就無法透過縮放網頁來達成放大字型 */
-webkit-appearance: none; /*可以改变按钮或者其它控件看起来类似本地的控件*/
-webkit-user-drag: none; /*-webkit-user-drag CSS 属性控制能否将元素作为一个整体拖动。*/
}
a{
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); /*很多Android 浏览器的 a 链接有边框,这里取消它 transparent */
}
/* For WebApp */
body{
-webkit-user-select : none; /* 如果用户长按web网页的文本内容,都会出现选中的行为,提供复制文字等功能。禁止用户选中文字 for iOS */
}
a, img{
-webkit-touch-callout:none; /* 在IOS浏览器里面,假如用户长按a标签,都会出现默认的弹出菜单事件。禁止用户在新窗口打开页面、如何禁止用户保存图片\复制图片 for iOS */
}
-
固定页面宽度
<meta name="viewport" content="width=320,user-scalable=0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-
触控面积
请保证将每条数据都放在一个 a 标签中,并设置其 display: block;,为何这样做?因为在触控手机上,为提升用户体验,尽可能的保证用户的可点击区域较大。
-
调用手机拨电话面板、短信面板
<a href="tel:18005555555">Call us at 1-800-555-5555</a>
<a href="sms:18005555555">
<a href="sms:18005555555,18005555556">
<a href="sms:18005555555?body="> //大都不支持body参数
安卓新系统支持程度都比较高,遗憾的是 iOS 新版反而不如旧版(旧版采用另外一种写法可以既支持号码又支持内容),详见下图:
-
去除 Android 平台中对手机、邮箱地址的识别
<meta content="email=no" name="format-detection" />
<meta content="telephone=no" name="format-detection" />
-
如何禁止用户旋转设备
iOS已经禁止开发者阻止 orientationchange 事件,那 Android 呢?对不起,我没有找到任何资料说 Android 禁止开发者阻止浏览器 orientationchange 事件,但是在 Android 平台,确实也是阻止不了的。
-
如何关闭 iOS 中键盘自动大写
当虚拟键盘弹出时,默认情况下键盘是开启首字母大写的功能的,根据某些业务场景,可能我们需要关闭这个功能,移动版本 webkit 为 input 元素提供了 autocapitalize 属性,通过指定 autocapitalize=”off” 来关闭键盘默认首字母大写。
另,设置是否使用输入的自动更正、自动不全、英文自动首字母大写。
<meta content="email=no" name="format-detection" />
<meta content="telephone=no" name="format-detection" />
-
IE8 CSS Selector
IE8 虽然提供 CSS Selector 的 querySelector()/querySelectorAll(),但搜索不了自定义标签,不过你可以用*[attrib=value]搜索,但效率较低。
-
检测是否视网屏幕
window.devicePixelRatio
-
浏览器是否支持"media queries"
window.matchMedia();
-
Android Android 的 webview 保存密码的问题
可用 WebViewClient 的 onReceivedHttpAuthRequest 事件监听。详见这里。
-
JS 添加 Do Not Track(DNT),保护访客隐私
大多数的网络浏览器的设置中有一个“Do Not Track”(DNT 即“不追踪”)设定,让用户能够控制自己的隐私信息被追踪的情况。 但是网站到底是否真的不追踪,还要看网站本身是否响应它 那么,做一个善良的网站,如果用户设置了Do Not Track,那么就保护一下他的隐私吧!
if(!navigator.doNotTrack){
// 这里面写搜集信息的脚本,如果开启DNT则不执行
}
同理,nodejs的:
var dnt=function(){
return (headers['HTTP_DNT']==1)
}
ref:http://blog.regou.me/?p=721
-
解决网站内容存在多个版本时,指定规范链接,帮助解决内容重复收录问题
<link rel="canonical" href="http://www.domain.com/index.html" />
有利于 SEO,注意地址不能跨域。
-
DNS Prefetch
<link rel="dns-prefetch" href="http://hm.baidu.com/">
DNS Prefetch也就是 DNS 预获取,也是前段优化的一部分。在前段优化中关于 DNS 的有两点:一是减少 DNS 的请求次数,第二个就是进行 DNS 预先获取。DNS Prefetch 应该尽量的放在网页的前面,推荐放在 <meta charset=”/> 后面。
-
Link Prefetching
<link rel="prefetch" href="http://daker.me/2013/05/hello-world.html" />
<link rel="prefetch" href="http://daker.me/assets/images/avatar.png" />
Link Prefetching 特性允许开发者在页面加载的时候预先加载他们希望指定的页面或元素。你也能够使用 prerendering 特性令你的网站速度更快,浏览器能够在后台获取并渲染整个页面,用户点击相应链接时再为用户展示该页面。
-
自适应布局模式
在编写 CSS 时,不建议把容器的宽度定死。为达到适配各种手持设备,对 ipad、itouch、ipod、iphone、android、web safarik、chrome 都能够正常的显示,你无需再次考虑设备的分辨率。
-
禁止浏览器默认行为
a, img{
/* 禁止用户在新窗口打开页面、如何禁止用户保存图片\复制图片 for iOS */
-webkit-touch-callout:none;
}
*{
/* 禁止用户选中文字 for iOS */
-webkit-user-select : none;
/*很多Android 浏览器的 a 链接有边框,这里取消它*/
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
安卓手机取消长按出现“复制”按钮的话,要修改 Webview 默认行为:
webView.setOnLongClickListener(new OnLongClickListener(){
public boolean onLongClick(View v) {
return true;
}
});
-
如何解决盒子边框溢出
当你指定了一个块级元素时,并且为其定义了边框,设置了其宽度为100%。在移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊的样式 -webkit-box-sizing:border-box; 用来指定该盒子的大小包括边框的宽度。
-
解决 CSS3 无法编写高光和内发光
这个时候你不妨使用 -webkit-border-image 来定义这个按钮的样式。 见下面正确代码和效果图:
<style type="text/css">
.bbb{width:300px; height:40px; line-height:40px;border:1px solid #dcdcdc;box-shadow:0px 0px 10px rgba(0,0,0,0.2) inset;border-radius:10px;}
</style>
<div class="bbb">ttttttttttttttttttttt</div>

-
iOS 4 没有 float:fixed
苹果用户一般都会升级他们的操作系统,升级到 iOS 5 之后的版本就可以了。因此可以不考虑该问题的兼容性。
-
使用 LESS 样式框架 include 模板问题
网页中只需 include xx.less 文件一次,其余的在那个 xx.less 中引入而不是与 xx.less 同级平衡,否则会出现重复加载的问题。
-
Android 2.x 样式 active 失效
其实点击那一下使用 cssSelecto:active 比 cssSelector:hover 更符合点击的效果,特别在列表滚动时尤其明显。但 Android 2.x 样式 active 失效,只好用 hover。如果用 js 实现,可参考如下:
/**
* 模拟 el:active
* @param {Element} ul 参数为<ul></ul>元素
*/
function onActive(ul){
// ONLY FOR Android 2.x? Yes!
// 检测是否 android 2.x 的属性,你可以依赖你自己的方案,我的就不贴了,比较简单的。
// if (!window.navigator.isAndroid_2) {
// return ul; //尽管该函数不工作,也要返回 this,以方便链式调用
// }
// add Highlight
ul.addEventListener('touchstart', function (e){
var targetEl = e.target;
while(targetEl && targetEl.tagName != 'LI'){// 默认为 li 修改样式
targetEl = targetEl.parentNode; // 找到要操作的目标元素为止
}
// do sth……
console.log(targetEl.tagName);
targetEl.addCls('active');
});
// remove Highlight
ul.addEventListener('touchend', function (e){
var targetEl = e.target;
while(targetEl && targetEl.tagName != "LI"){
targetEl = targetEl.parentNode; // 找到要操作的目标元素为止
}
// do sth……
console.log(targetEl.tagName);
targetEl.removeCls('active');
});
return ul; // 方便链式调用
}
CSS 样式如下:
/* 点击效果 */
ul.x_list li:active, ul.x_list li.active {
background-image: -webkit-gradient(linear, center top, center bottom, from(lightGrey), to(white));
}
-
阻止页面整体滚动
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);
-
去掉浏览器地址栏
window.setTimeout(scrollTo, 0, 0, 0);
这句代码必须放在 window.onload 里才能够正常的工作,而且你的当前文档的内容高度必须是高于窗口的高度时,这句代码才能有效的执行。
-
iOS 中如何获取滚动条的值
桌面浏览器中想要获取滚动条的值是通过 document.scrollTop 和 document.scrollLeft 得到的,但在 iOS 中你会发现这两个属性是未定义的,为什么呢?因为在 iOS 中没有滚动条的概念,在 Android 中通过这两个属性可以正常获取到滚动条的值,那么在 iOS 中我们该如何获取滚动条的值呢?通过 window.scrollY 和 window.scrollX 我们可以得到当前窗口的 y 轴和 x 轴滚动条的值。
-
无法使用 Applicatipon Cache
可以考虑使用 localStorage 代替。
-
复位 Applicatipon Cache 的一个办法
在我们的3G版网站的项目中使用了html5 application cache,将大部分图片资源、js、css等静态资源放在manifest文件中。没想到上线第一天就遇到了严重问题:application cache会默认缓存当前页面!!!就算我们有如下设置:NETWORK:*也就是说,对于所有的动态页面,application cache会缓存起来,用户怎么刷新都是老的!而且手机浏览器还很难清除掉,也不支持js清除!花了一个上午,尝试了很多办法,查了很多资料,都没能清除掉客户端的缓存。一上午被用户投诉惨了。最后还是万能的stackoverflow救了我:
Do not use appcache unless it is REALLY 100% EXACTLY WHAT YOU WANT TO DO Even if it IS 100% EXACTLY WHAT YOU WANT TO DO,
*DO NOT* use appcache until you are 100% CERTAIN that you are not going to make a single change to that page (or any file that it links to) for a LONG time. Delete the manifest file from the server -- if the browser can't find the manifest file, then it will clear its cache... ...this will also turn caching off for everyone. Don't turn it on again until it's 100% CORRECT Dealing with appcache is miserable, often.
解决办法很简单,在服务器端删除掉manifest文件,并且慎用application cache
-
Safari 日期转换
这是 Safari 浏览器的一个 bug,故桌面版和移动版都会有。不能用常规的 Date.format 方法解析日期类型。可尝试一下下面的补丁。
var regexp = /[- :]/;
var _begin = (program.begin).split(regexp);
var _end = (program.end).split(regexp);
var begin = new Date(_begin[0], _begin[1]-1, _begin[2], _begin[3], _begin[4], _begin[5]);
var end = new Date(_end[0], _end[1]-1, _end[2], _end[3], _end[4], _end[5]);
var now = new Date;
var arr = (program.begin).split(regexp);
//var date = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);
-
iOS 不能override UserAgent?
如果是的话,那就缺乏轻松识别“基座模式”的途径。在 Android 上,重写 ua 却是一件轻易的事情。不过可以用以下方法代替:window.navigator.standalone 可用于判断当前web app是否从主屏启动。注意,这只在ios设备有效。
-
区域滚动
要在一个 div 产生一个可滚动的区域,默认下是完全没有硬件加速的滚动效果的,效率很差,一顿一顿的滚动用户体验相当的不好。无论 iOS 和 android 都是,即使你使用 iframe 的也不行。不过苹果开发人员能意识到这个问题真的很“蛋疼”,从 iOS 5 开始于 overflow 项提供一个 scroll 的属性,使得苹果手机上可以有加速的区域滚动。但反观安卓方面,似乎很不负责任,到 4.1 都没有收到风声说优化此问题。解决方案有很多种,有人也曾经归纳过。比较主流的方法使用 iScroll 库。
-
Android 4.0.下 touchend 滑动不能触发
又是一个很蛋疼的问题。
-
Android 4.0 transform 3D 极慢
综上安卓 4.x WebView 所带来的问题,只能说,新的版本不一定好。android 2.x 都没有该问题。
-
制作跑马灯特效时的两个移动的不同
尽管两者同时作用于一个控件(或 div )之上,但其性质是不一样的,一个是平移(move),相对于 D&D 的水平方向移动,是跟随手指移动着的;另外一个是滚动(scrollTo),跳到指定的哪一帧。
-
制作跑马灯使用 left/top 与使用 transformX/Y 的不同
坐标系没有发生变化。不过 css3 的方式可以要求 mover 元素不为绝对定位。
-
检测是否已连网,以及网络速度
最通用的:
if (window.navigator.onLine) {
alert('online')
} else {
alert('offline');
}
// in IE 8 "online" and "ofline" events are raised on the document.body, under IE 9 - on both document.body and window
window.addEventListener("offline", function(e) {alert("offline");});
window.addEventListener("online", function(e) {alert("online");});
判断是否 wifi 网络
if (navigator.connection.type==navigator.connection.WIFI) {
// code for WiFi connections (high-bandwidth)
}
写成一个函数:
/**
* 检测是否已连网,以及网络速度。
* @return {String} [description]
*/
function netDetect(){
//alert(window.navigator.userAgent);
var connection, connectionSpeed;
// create a custom object if navigator.connection isn't available
connection = navigator.connection || {'type':'0'};
switch(connection.type){
case connection.ETHERNET:
case connection.WIFI:
connectionSpeed = 'highbandwidth';
break;
case connection.CELL_3G:
connectionSpeed = 'mediumbandwidth';
break;
case connection.CELL_2G:
connectionSpeed = 'lowbandwidth';
break;
case connection.UNKNOWN:
default:
connectionSpeed = 'noConnect';
}
return connectionSpeed;
}
function is_Android_Wifi(){
var connection = navigator.connection;
if(window.navigator.isAndroid && (connection.type == connection.ETHERNET || connection.type == connection.WIFI))
return true;
else return false;
}
-
iOS 5 下通过 url 快速访问应用
他们是直接将网页进行Base64编码,省的创建一堆页面,将该页面添加到主屏幕后 meta里的图标信息就生效了,伪装成一个系统应用,然后再点击开这个伪装的应用的时候 js判断 window.navigator.standalone==true 的时候 触发点击 href=“prefs:root=MESSAGES” 。最核心的是iOS5 可以href prefs:访问到应用,window.navigator.standalone的判断很巧妙,base64解码一下就清楚了。
参考:
http://www.zhihu.com/question/19916323/answer/13342363
http://holgr.com/blog/2011/11/no-jailbreak-necessary-how-to-quickly-access-ios-settings-on-your-ipad-iphone-or-ipod/
-
事件委托 Event Delegation 之循环 vs 递归
都是集中在如何获取父级元素(因为是“冒泡”所以是获取父元素,如果是“捕获”方式则是获取子元素)。初步看了, 循环好一点,起码不会死循环。
// 递归方式
/**
* this 应为 CSS Selector
* @param {Event} e
*/
function removeHighlight(e){
var targetEl = e.target;
if(targetEl && targetEl.tagName == this.toUpperCase()){
targetEl.removeCls('active');
}else if(targetEl){
arguments.callee.call(this, {
target : targetEl.parentNode
});
}
}
ul.addEventListener(highEvent_out, removeHighlight.bind(el_cssSelector || 'LI'));
// 循环方式
function removeHighlight(e){
var targetEl = e.target;
while(targetEl && targetEl.tagName != 'LI'){// 默认为 li 修改样式
targetEl = targetEl.parentNode; // 找到要操作的目标元素为止
}
// do sth……
console.log(targetEl.tagName);
targetEl.removeCls('active');
}