美文网首页程序员
移动端开发系列——Hack

移动端开发系列——Hack

作者: 犯迷糊的小羊 | 来源:发表于2017-02-28 16:44 被阅读154次

    导语

    这期讲一下移动端开发时常见到的一些问题,内容包括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触发或所有的元素都使用触发;

    相关文章

      网友评论

        本文标题:移动端开发系列——Hack

        本文链接:https://www.haomeiwen.com/subject/sjfnwttx.html