移动端开发系列——Hack

导语

这期讲一下移动端开发时常见到的一些问题,内容包括1像素边框、300ms延迟以及zepto的tap的bug,下面的所有代码均在chrome的iPhone6Plus的设备模拟器环境下测试;

1像素边框的问题

出现1px边框的问题由来

iPhone的dpr>=2,1px由4dp构成,相当于宽高都放大1倍,它们显示出2dp的效果,PC端由于尺寸较大,所以差距不明显,但是在移动端的小屏幕上,差距就非常突出;


移动端开发系列——Hack_第1张图片
1像素在PC端的显示效果

所以这就是为什么在PC端设置1px,在dpr>=2的移动端会显示出"2px"的效果;

解决问题的思路是:进行设备检测,当dpr>=2并且为移动设备时,去除PC端设置的border,添加适配移动端元素的border的类,具体就是将border缩放为原来的0.5

如果只是给元素添加下边框,可以采用以下hack方案:

1px border question
.foo{ position: relative; } .foo::after{ content:''; width: 100%; display: block; postion: absolute; bottom: 0; border: 1px solid; transform: scaleY(0.5) }

如果给元素添加全边框,可以采用一下方案:

1px border question
.onePixel{ position: relative border: none; &::after{ content:''; display: block; border: 1px solid; box-sizing: border-box; width: 200%; height: 200%;//缩放0.5后,变为100%; transform: scale(0.5); position: absolute; top: 0; left: 0; } } if(window.devicePixelRatio && window.devicePixelRation>=2 && /iPhone/i.test(navigator.userAgent)){ document.querySelector('.foo').className = 'foo onePixel' }

移动端开发系列——Hack_第2张图片
移动端的显示效果

完整代码见 code,童鞋们可以打开设备模拟器放大到150%自行观察区别;


300ms延迟

移动端的click事件触发后慢上300ms

默认的viewport都是980px->许多页面将缩放显示-> 用户往往初次进入时需要双击页面 -> 为了判断是否双击,当点击之后给予300ms的反应时间

移动端开发系列——Hack_第3张图片
click 300ms

click 300ms

如何破解300ms问题?

  • 为head添加viewport

上述元信息表明默认不进行缩放,按照设备尺寸去设置viewport;
既然设备知道不用缩放,所以也就不用响应300ms;
但缺点是万一用户要缩放呢?
code

  • 使用tap事件代替click事件,是自定义的click事件
    zepto库提供了click事件的替代事件tap;

tap事件的原理

zepto的源码是点击后点击位置不超过30像素,则在250ms后出发tap事件;


移动端开发系列——Hack_第4张图片
tap事件原理

tap的bug——点透

看了些资料,据闻zepto的tap事件在有两个元素层叠的时候,上层蒙层元素监听tap事件点击后消失,下层元素监听click事件,会发生点透的bug;

为什么?

tap事件的延迟是250ms,click是300ms,所以当上层元素在250ms触发后消失,下层元素再过50ms才接受到click事件,所以会发生类似的现象;

这个bug本质就是打个时间差,上层元素250ms反应,下层元素300ms才反应;
code

tap的解决方案

  • 最简单的就是,上下层元素都用tap,缺点是只适用于移动端;
    code

  • 调整上层元素的消失时间呗,让它在300ms后消失;
    code


总结:

  • 由于手机设备的dpr缘故导致1px的显示效果在PC端和手机端显示不一致,解决方案是通过在元素内部添加伪类的方式制造出经过缩放0.5倍的1px边框;
  • 由于以前手机端往往在初次进入页面时需要双击缩放,所以iPhone设置了一个300ms毫秒的方法响应用户操作,由此也带来了不小的麻烦;
  • 解决300ms方案包括设置viewport和或者是采用tap事件;
  • tap事件又会带来点透的bug,解决方案可以是延迟tap触发或所有的元素都使用触发;

你可能感兴趣的:(移动端开发系列——Hack)