每天一剂 WebView 良药-阿里云开发者社区

开发者社区> sp42> 正文

每天一剂 WebView 良药

简介: 标签类 Web App 建议用的样式 用于覆盖 WebView 默认的样式,使得 App 看起来更像原生的 App,——“不露出马脚” /* document.documentElement.style.
+关注继续查看

标签类

  1. 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 */  
    } 

  2. 固定页面宽度

    <meta name="viewport" content="width=320,user-scalable=0" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/> 
    
  3. 触控面积

    请保证将每条数据都放在一个 a 标签中,并设置其 display: block;,为何这样做?因为在触控手机上,为提升用户体验,尽可能的保证用户的可点击区域较大。

  4. 调用手机拨电话面板、短信面板

    <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 新版反而不如旧版(旧版采用另外一种写法可以既支持号码又支持内容),详见下图:

  5. 去除 Android 平台中对手机、邮箱地址的识别

    <meta content="email=no"     name="format-detection" />
    <meta content="telephone=no" name="format-detection" />
    
  6. 如何禁止用户旋转设备

    iOS已经禁止开发者阻止 orientationchange 事件,那 Android 呢?对不起,我没有找到任何资料说 Android 禁止开发者阻止浏览器 orientationchange 事件,但是在 Android 平台,确实也是阻止不了的。

  7. 如何关闭 iOS 中键盘自动大写

    当虚拟键盘弹出时,默认情况下键盘是开启首字母大写的功能的,根据某些业务场景,可能我们需要关闭这个功能,移动版本 webkit 为 input 元素提供了 autocapitalize 属性,通过指定 autocapitalize=”off” 来关闭键盘默认首字母大写。

    另,设置是否使用输入的自动更正、自动不全、英文自动首字母大写。

    <meta content="email=no"     name="format-detection" />
    <meta content="telephone=no" name="format-detection" />
    
  8. IE8 CSS Selector

    IE8 虽然提供 CSS Selector 的 querySelector()/querySelectorAll(),但搜索不了自定义标签,不过你可以用*[attrib=value]搜索,但效率较低。

  9. 检测是否视网屏幕

    window.devicePixelRatio
  10. 浏览器是否支持"media queries"

    window.matchMedia();
  11. Android Android 的 webview 保存密码的问题

    可用 WebViewClient 的 onReceivedHttpAuthRequest 事件监听。详见这里。

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

  13. 解决网站内容存在多个版本时,指定规范链接,帮助解决内容重复收录问题

    <link rel="canonical" href="http://www.domain.com/index.html" /> 

    有利于 SEO,注意地址不能跨域。

  14. DNS Prefetch

    <link rel="dns-prefetch" href="http://hm.baidu.com/">
    

    DNS Prefetch也就是 DNS 预获取,也是前段优化的一部分。在前段优化中关于 DNS 的有两点:一是减少 DNS 的请求次数,第二个就是进行 DNS 预先获取。DNS Prefetch 应该尽量的放在网页的前面,推荐放在 <meta charset=”/> 后面。

  15. 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 特性令你的网站速度更快,浏览器能够在后台获取并渲染整个页面,用户点击相应链接时再为用户展示该页面。

样式类

  1. 自适应布局模式

    在编写 CSS 时,不建议把容器的宽度定死。为达到适配各种手持设备,对 ipad、itouch、ipod、iphone、android、web safarik、chrome 都能够正常的显示,你无需再次考虑设备的分辨率。

  2. 禁止浏览器默认行为

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

  3. 如何解决盒子边框溢出

    当你指定了一个块级元素时,并且为其定义了边框,设置了其宽度为100%。在移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊的样式 -webkit-box-sizing:border-box; 用来指定该盒子的大小包括边框的宽度。

  4. 解决 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>

  5. iOS 4 没有 float:fixed

    苹果用户一般都会升级他们的操作系统,升级到 iOS 5 之后的版本就可以了。因此可以不考虑该问题的兼容性。

  6. 使用 LESS 样式框架 include 模板问题

    网页中只需 include xx.less 文件一次,其余的在那个 xx.less 中引入而不是与 xx.less 同级平衡,否则会出现重复加载的问题。

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

页面特效类

  1. 阻止页面整体滚动

    document.body.addEventListener('touchmove', function(event) {
      event.preventDefault();
    }, false); 
  2. 去掉浏览器地址栏

    window.setTimeout(scrollTo, 0, 0, 0);
    

    这句代码必须放在 window.onload 里才能够正常的工作,而且你的当前文档的内容高度必须是高于窗口的高度时,这句代码才能有效的执行。

  3. iOS 中如何获取滚动条的值

    桌面浏览器中想要获取滚动条的值是通过 document.scrollTop 和 document.scrollLeft 得到的,但在 iOS 中你会发现这两个属性是未定义的,为什么呢?因为在 iOS 中没有滚动条的概念,在 Android 中通过这两个属性可以正常获取到滚动条的值,那么在 iOS 中我们该如何获取滚动条的值呢?通过 window.scrollY 和 window.scrollX 我们可以得到当前窗口的 y 轴和 x 轴滚动条的值。

  4. 无法使用 Applicatipon Cache

    可以考虑使用 localStorage 代替。

  5. 复位 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

  6. 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]);
    
  7. iOS 不能override UserAgent?

    如果是的话,那就缺乏轻松识别“基座模式”的途径。在 Android 上,重写 ua 却是一件轻易的事情。不过可以用以下方法代替:window.navigator.standalone 可用于判断当前web app是否从主屏启动。注意,这只在ios设备有效。

  8. 区域滚动

    要在一个 div 产生一个可滚动的区域,默认下是完全没有硬件加速的滚动效果的,效率很差,一顿一顿的滚动用户体验相当的不好。无论 iOS 和 android 都是,即使你使用 iframe 的也不行。不过苹果开发人员能意识到这个问题真的很“蛋疼”,从 iOS 5 开始于 overflow 项提供一个 scroll 的属性,使得苹果手机上可以有加速的区域滚动。但反观安卓方面,似乎很不负责任,到 4.1 都没有收到风声说优化此问题。解决方案有很多种,有人也曾经归纳过。比较主流的方法使用 iScroll 库。

  9. Android 4.0.下 touchend 滑动不能触发

    又是一个很蛋疼的问题。

  10. Android 4.0 transform 3D 极慢

    综上安卓 4.x WebView 所带来的问题,只能说,新的版本不一定好。android 2.x 都没有该问题。

  11. 制作跑马灯特效时的两个移动的不同

    尽管两者同时作用于一个控件(或 div )之上,但其性质是不一样的,一个是平移(move),相对于 D&D 的水平方向移动,是跟随手指移动着的;另外一个是滚动(scrollTo),跳到指定的哪一帧。

  12. 制作跑马灯使用 left/top 与使用 transformX/Y 的不同

    坐标系没有发生变化。不过 css3 的方式可以要求 mover 元素不为绝对定位。

  13. 检测是否已连网,以及网络速度

    最通用的:

    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;
    }
  14. 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/

  15. 事件委托 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');
    }
    

开发、调试技巧

  1. 手机上不容易复制、粘贴,有啥好办法?

    可以通过 QQ 发消息,但多个 QQ 同时登陆又有另外衍生的问题。如果是网址,推荐使用二维码的方式。给手机装个二维码扫描软件,然后把 url 放到在线的二维码生成,如http://www.liantu.com/,之后用扫一下就可以啦。

  2. 使用 SourceMap 时记得要把未压缩、未混淆的文件也放上去。


Bugs:

IOS4的日期类转换时有问题

http://stackoverflow.com/questions/5324178/javascript-date-parsing-on-iphone


Click事件tap事件傻傻分不清


AppCachemanifest)在phonegap模式下失效。

http://www.sencha.com/forum/showthread.php?175104-iOS-Fullscreen-webapp-manifest-file-gets-ignored


AppCache测试的地址:

回流 reflow重绘repaint问题

http://www.blogjava.net/BearRui/archive/2010/05/10/web_performance_repaint_relow.html

p.s Web页面性能测试工具,分别是:dynaTrace(测试ie),SpeedTracer(测试Chrome)


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
2171 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
3956 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
9307 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
721 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
16274 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
2901 0
+关注
sp42
移动项目技术负责人。多年全栈经验,熟悉 Java 和 JS,CSDN 博客技术专家,著有《ExtJS 详解与实践》等书。
294
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载