移动端开发系列——Hack

导语

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

1像素边框的问题

出现1px边框的问题由来

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


1像素在PC端的显示效果

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

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

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

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

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

<div class="foo">
    1px border question
</div>
.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'
}

移动端的显示效果

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


300ms延迟

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

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

click 300ms

click 300ms

如何破解300ms问题?

  • 为head添加viewport
<meta name="viewport" content="width=device-width,initial-scale=1,max-scale=1,no-scalable=no">

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

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

tap事件的原理

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


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触发或所有的元素都使用触发;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容