UC、Chrome、Safari、QQ浏览器、百度浏览器、360浏览器等手机上的浏览器几乎全部都是基于webkit内核
首先采用百分比自适应布局(即流式布局)
同时,需要对一定段的viewprot视口进行设置,就能达到适配的目的
浏览器上承载着viewport,viewport承载着网页。
viewport是一个虚拟的窗口,它支持放大缩小。
在移动端用来承载网页的一个区域,就是我们的视觉窗口–viewport。这个区域可以设置宽高,可以按比例放大缩小,而且能设置是否允许用户自行缩放。
viewport有默认的宽高,在iphone4中默认为980px*1000px。二手机屏幕的宽高并没有这么多,故此之鞥将网页缩放显示在屏幕上,这样势必会导致网页的内容特别小,看不清。
所以现在就需要将viewport设置成和手机屏幕相同的尺寸就OK。设置方法:
<meta name="viewport" content="width=device-width;initial-scale=1.0;user-scalable=no;minimum-scale=1.0;maximum-scale=1.0">
使用meta标签吧viewport的宽度设为device-width,同事initial-scale=1.0,user-scalable=no
rgba中的第四个值可以设置透明度,它与opacity不同的是,它的透明度设置不会影响盒子中的内容的透明度,而opacity设置之后连内容也随之变模糊了。
切图面对的问题:如果按照1:1的显示在移动设备当中图片会失真。
原因是:在高清屏中会用两个或两个以上的物理像素来显示实际的1px图片内容,那么其实就是相当于把1px的图片放大显示了,所以有毛边的图片一般都会失真,也就是显示模糊。
解决方案:采用压缩图片尺寸的方式来解决。
如果是img直接设置宽高的方式来压缩;
如果是background-image设置background-size的方式来压缩
基线:abcdyxz这行字母的y底下就会多出一点来,这是因为文字以基线对齐。同样的,img标签也是inline-block元素,以基线对齐,底下就会出现一小点空白。
解决方案:
移动端浏览器提供一个特殊的功能:双击(double tap)放大。
300ms的延迟就是来自这里,用户碰触页面之后,需要等待一段时间来判断是不是双击动作,而不是立即响应单击(click),等待的这段时间大约是300ms。
移动端事件提供touchstart、touchmove、touchend却没有提供tap的支持,主流框架(库)都是手动实现了自定义的tap事件,以求消除300ms的延迟,提高页面的响应速度。
混用tap和click就会导致点击穿透的问题,因为click是在tap系列事件发生后大约300ms才触发的。
1)点击蒙层(mask)上的关闭按钮,蒙层消失时发现触发了按钮下面元素的click事件
蒙层的关闭按钮绑定的是tap事件,而按钮下面元素绑定的是click事件,tap事件触发后,蒙层消失了,300ms这个点的click事件fire,event的target自然就是按钮下面的元素,因为按钮跟蒙层一块消失了。
2)如果按钮下面恰好是一个href属性的a标签,那么页面就会发生跳转。
因为a标签跳转默认是click事件触发。
3)直接点击页内按钮跳转至新页面,然后发现新页面中对应位置元素的clic事件被触发了。
问题已经很明了了,有很多解决方案,但思路不外乎2种:
1)不要混用tap和click
既然tap之后300ms会触发click,只用tap或者只用click就自然不会存在问题了
2)吃掉(或者说消费掉)tap之后的click
依旧用tap,只是在可能发生点击穿透的情形做额外的处理,拿个东西来挡住、或者tap后延迟350毫秒再隐藏mask、pointer-events、在下面元素的事件处理器里做检测(配合全局flag)等等,能吃掉就行
详细解决方案:
1)只用touch
最简单的解决方案,完美解决点击穿透问题
把页面内所有click全部换成touch事件( touchstart 、’touchend’、’tap’), 需要特别注意 a标签,a标签的href也是click,需要去掉换成js控制的跳转,或者直接改成span + tap控制跳转。如果要求不高,不在乎滑走或者滑进来触发事件的话,span + touchend就可以了,毕竟tap需要引入第三方库
不用a标签其实没什么,移动app开发不用考虑SEO,即便用了a标签,一般也会去掉所有默认样式,不如直接用span
2)只用click
下下策 ,因为会带来300ms延迟,页面内任何一个自定义交互都将增加300毫秒延迟,想想都慢
不用touch就不会存在touch之后300ms触发click的问题,如果交互性要求不高可以这么做, 强烈不推荐 ,快一点总是好的
3)拿个东西来挡住
比较笨的方法, 千万不要用
4)tap后延迟350ms再隐藏mask
改动最小,缺点是隐藏mask变慢了,350ms还是能感觉到慢的
只需要针对mask做处理就行,改动非常小,如果要求不高的话,用这个比较省力
5)pointer-events
比较麻烦且有缺陷, 不建议使用
mask隐藏后,给按钮下面元素添上 pointer-events: none; 样式,让click穿过去,350ms后去掉这个样式,恢复响应
缺陷是mask消失后的的350ms内,用户可以看到按钮下面的元素点着没反应,如果用户手速很快的话一定会发现
开发的页面在Android上面看时,页面的顶部是在状态栏以下的位置的,而在ios上面看时,页面的顶部和状态栏顶部对齐了,即页面上边部分内容被状态栏挡住了,出现这个问题的原因是iphone讲求“全屏布局”。
解决问题的办法就是:
在一个公共的(每个页面都需要引入)js文件中,加入以下代码,动态判断当前是不是IOS系统,如果是,则在页面顶部加入大约15px高度的一个div
var u = navigator.userAgent;
var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if(isIOS){
var perDiv = '';
$(".sinoiov-bar-nav").before(perDiv).css("top","1.4rem");
$(".sinoiov-has-header").css("margin-top","6.3rem");
}
*,::before,::after{ margin:0; padding:0; /*清楚移动端默认点击高亮*/ -webkit-tap-heightlight-color:transparent; /*因为使用百分比布局,如果加上padding或者border,就有可能超出屏幕宽度,故设置盒子尺寸以边框开始计算*/ -webkit-box-sizing:border-box; box-sizing:border-box; }
body{ font-size:16px; font-family:"MicroSoft YaHei",Sans-Serif; color:#333; }
a{ color:#333; text-decoration:none; }
a:hover{ text-decoration:none; }
ul,ol{list-style:none;}
input{ border:none; outline:none; /*清除移动端默认表单样式*/ -webkit-appearance:none; }
.left{float:left;}
.right{float:right;}
.clearfix::before,.clearfix::after{ content:''; height:0; line-height:0; display:block; visibility:hidden; clear:both; }
可以使用JavaScript中的history.go(-1)
的方式实现返回按钮,但是这样做有很大的局限性。就是只能是一级一级向上返回,有时候业务逻辑并不是一级一级返回的。最常见的场景就是充值,付款时。
这时就需要自己实现上述功能。实现的思路是每请求一次URL,判断栈最后面的URL是否等于当前的URL,如果不等于,则就向栈中push当前的URL,如果等于,则什么都不做;点击返回按钮时,pop掉栈中最后一个元素,并重定向到栈中的最后一个URL。
(function(){ function Vehicle(){} Vehicle.prototype = { setHistory:function(url){ var historyArray = JSON.parse(localStorage.getItem("historyArray")); if(!historyArray){ historyArray = []; historyArray.push(url); }else{ if(historyArray[historyArray.length -1] != url){ historyArray.push(url); } } localStorage.setItem("historyArray",JSON.stringify(historyArray)); }, goBack:function(){ var historyArray = JSON.parse(localStorage.getItem("historyArray")); if(historyArray.length > 1){ historyArray.pop(); localStorage.setItem("historyArray",JSON.stringify(historyArray)); } window.location.href = historyArray[historyArray.length-1]; } }; window.vehicle = new Vehicle(); })();
localStorage.clear();
window.vehicle.setHistory(window.location.href);
window.vehicle.goBack();