zoukankan      html  css  js  c++  java
  • 移动端二三事【二】:移动端触摸事件点透及多种解决方案。

    大家都知道的少说,多分享一些干货。

    一、首先说移动端的三大主要事件:

    1.手指按下: ontouchstart
    2.手指移动:ontouchmove
    3.手指抬起 ontouchend

    *使用移动端事件时,为尽可能地保证兼容性与调试时的友好性,尽可能用事件绑定的方式。例如:

    /*
    注意:
    在移动端开发的时候,浏览器的模拟器时好时坏,一般不用on的方式绑定事件函数,要用事件绑定的方式(addEventListener)。
    */
        //用以下方式浏览器的移动端模拟器可能会无法识别事件
        var div = document.getElementById('div1');
        
        div.ontouchstart = function(){
            alert(1);
        }

    所以一般采用以下方式:

    div.addEventListener('touchstart',fn);

    二、pc端事件与移动端事件的主要区别

    与PC端的事件相比,移动端的触摸事件会比click事件快300毫秒,这300毫秒的由来是这样的(听公司某一大神说的):当初最早使用屏幕的双击缩放功能的是Safari浏览器,开发之初,为了判断用户行为(用户是想点击链接还是想双击缩放屏幕),所以规定以第一次点击(并非常规的click)时间比常规click提前300毫秒,而本次点击之后300毫秒内,如果用户再次点击,则会触发双击事件。若300毫秒内用户没有再次点击,则会触发click事件。而刚才说的第一次的点击,发展到今天也就成了移动端的触摸事件,所以常规的click会比触摸事件晚300毫秒。

    三、移动端点透

    正是因为这300毫秒的提前,会使移动端事件出现一个系统性的bug。

    举个栗子,如下图:透明的红色div绝对定位,a链接基于常规文档流,在div的底层。

    现在为红色div添加touchend事件,触摸后使红色div的display为none,而红色div消失后,页面跳转至a标签指定的链接地址。根据上面对移动端事件提前300毫秒的解释,可知touchend事件触发后300毫秒,再次触发click事件,进而触发a标签的默认行为。

    四、点透的多种解决方案

    方案一:下层不使用有点击行文或获取焦点行为的元素(淘宝移动端)

    截图如下:

    淘宝的解决方案:并没有使用a链接,而是为其加上了自定义属性。

    缺点:对于小公司的开发团队,不利于seo优化,适合流量入口众多的大公司。其次,此方法并没有从根本上解决问题,底层不能出现绑定有click事件的元素。

    方案二:对于一些浮层,或对响应时间要求不是很高的页面,使用click事件。

    缺点:存在局限性。

    方案三(推荐):最常用的,移动端项目利用事件冒泡完全摒弃pc端事件:

    //底层结点阻止默认行为
    document.addEventListener('touchstart',function(ev){
        ev.preventDefault();
    });

    缺点:a链接等可获取焦点的元素的默认行为无法使用,需手动添加时间绑定。原理如下:

    var a = document.getElementById('testA');
    a.addEventListener('touchstart',function(){
        window.location.href = 'http://www.baidu.com';
    });

    五:点透及阻止点透的实际应用

    *以下问题均可利用pc端的阻止默认行文解决:

        document.addEventListener('touchstart',function(ev){
            ev.preventDefault();
        });

    1.解决禁止用户缩放的兼容性问题。

    //IOS10下设置meta无法禁止用户缩放,利用阻止默认行文就可解决。
    <meta name="viewport" content="width=device-width,user-scalable=no"/>

    2.解决IOS10下溢出隐藏的问题。

    //IOS10下横向滚动条通过以下方式,无法溢出隐藏
    //利用阻止默认行文即可解决 body,html
    { width: 100%; overflow: hidden; }

    3.阻止橡皮筋效果(页面移动到最底部或最顶部的缓冲反弹效果)

    4.禁止长按选中文字、选中图片、弹出菜单等

    5.阻止默认行文后,元素无法获取焦点,阻止冒泡后可正常使用。

    inputNode.addEventListener('touchstart',function(ev){
        ev.stopPropagation();
    });

    六:总结

    利用阻止默认行文是最好的解决方案,不但能解决点透问题,还能解决多种兼容问题。

  • 相关阅读:
    css文字换行问题white-space:pre-line或者white-space:pre-wrap,解决word-wrap:break-word解决不了的
    ie浏览器检测不到cookie的问题
    jQuery ajax在IE浏览器的跨域问题--jquery.xdomainrequest.min.js
    移动端 input 获取焦点后弹出带搜索、确定、前往的键盘,以及隐藏系统键盘
    三个获取浏览器URL中参数值的方法
    上传文件时文件类型限制 <input id="File1" type="file" accept=""/>
    ES6 let和const 的相同点与区别
    html页面中的title设置为空格
    vue 之 key
    nginx 之 proxy_pass详解
  • 原文地址:https://www.cnblogs.com/pomelott/p/7774996.html
Copyright © 2011-2022 走看看