zoukankan      html  css  js  c++  java
  • WAP端 穿透问题和解决方法

    1. 穿透问题可这么理解, 共有2种问题:
      问题1: 有A 和 B 两个弹层,B 弹层盖在A 弹层上面,B 弹层绑定 touchend 事件,当用户点击B 的时候 B隐藏,由于touchend 事件触发的太快了,导致用户点击到弹层下面的具有click 属性的元素的东东。(包括 A 标签<a href='#'></a> 或 input 框 或 绑定了 click 事件的元素)

      奇怪的是, 若给链接A 绑定了touchend 并且e.preventDefault() 也是不起作用。请看下面的例子,也就是它根本没有执行 touchend 事件,但是却执行了A 元素的 href 跳转链接。

    <a href='https://www.baidu.com/'></a>
    
    <script type='text/javascript'>
      // B 是在 a 链接上面的弹层
      B.on('touchend', function(){
        B.hide();
      });
    
      // 大部分浏览器都不会执行 console.log,但是 ios 8.4 safari 不跳转,因为它本来就没有穿透问题。
      $('a').on('touchend', function(e){ 
        console.log('touchend');
        e.preventDefault(); 
      });
    </script>

    浏览器表现 :
      ios 8.4 safari 页面不跳转
      ios 8.4 UC 10.6.5.627 跳转
      ios 7.0 safari 跳转
      ios 7.0 UC 10.6.5.627 跳转
      SAMSUNG GT-19308 4.3 UC 10.6.5.627 跳转
      SAMSUNG GT-19308 4.3 跳转。 若直接点击链接 a,竟然会跳转,e.preventDefault() 竟然没作用,只有这个浏览器会。想点击 a 链接不跳转,只能绑定 click 事件并且 e.preventDefault();

      问题2:有A 和 B两个元素,B 元素盖在A 元素上面,B元素默认隐藏。A元素绑定事件让B 元素显示出来,B元素点击自己隐藏。出现的现象是: 点击A元素 B元素显示不出,因为触发了B元素里的代码。

    A.on('touchend', function(){
      B.show();
    });
    
    // 就算B 元素用 touchend 绑定, 有的手机也还是会触发 B.hide();
    B.on('click', function(){
      B.hide();
    });

    解决穿透问题1: 

    各个浏览器的表现
      iOS 8.4 safari用touchend 关闭 不会穿透下面绑定的 click 事件, 所以什么事都不用做,很完美。
      iOS 8.4 和 iOS 7.0 UC浏览器弹窗关闭用 setTimeout(function(){ 弹层.hide() }, 0); 可以解决弹层穿透。
      另外备注下: UC 浏览器做过优化,下面的代码 click 事件比 touchend的触发的快。

    $('.m').on('touchend', function(){
        setTimeout(function(){
            console.log('touchend');
        }, 0);
    });
    
    $('.m').click(function(){
        console.log('click');
    });

    iOS 7.0 safari的不行,只能用 e.preventDefault() 解决 或者设置 setTimeout(.. 360),而 e.preventDefault() 也支持 ios8.4 safari和UC版本的。

    Android 的手机 4.1.1 JRO03L MIUI-JLB14.0, e.preventDefault();不能解决,但是 setTiemout 只要在 >=300 就可以解决了。

    所以最终的解决办法:

      由于 iOS 7.0上 setTimeout 360毫秒 的时间太长了,所以直接给 B弹层绑定 e.preventDefault();

    B.on('touchend', function(e){
        e.preventDefault();
        B.hide();
    });

       Android上解决方式通过属性 pointer-events: none; 让整个页面都不能有点击的属性, 301秒以后恢复属性值。

    B.on('touchend', function(){
        $('html').css({
            pointer-events: 'none'
        });
        setTimeout(function(){
            $('html').css({
                pointer-events: 'auto'
            });
        }, 301);
    
        B.hide();
    });

    解决穿透问题2:

      解决方式比较简单, A 里面用 e.preventDefault(), 注意A也不能绑定tap; B 绑定 touchend

    A.on('touchend', function(e){
        e.preventDefault();
        B.show();
    });
    
    
    B.on('touchend', function(){
        B.hide();
    });

    2. 当给一个元素绑定 touchend 事件和click事件, touchend事件让元素关闭,那么都不会触发到 click 事件,浏览器如下。
      SAMSUNG GT-19308 4.3 原生浏览器 和 UC浏览器 10.6.5.627
      IOS7.0 safari 和 UC浏览器 10.6.5.627
      IOS8.4 safari 和 UC浏览器 10.6.5.627

    3. fastClick

    通过绑定 body touchend,然后通过逻辑找到 e.target 元素,满足条件下执行 e.preventDefault(); 阻止了 click事件,然后让 initMouseEvent 和 dispatchEvent 来触发。

    问题1的是否解决 的浏览器兼容如下:

    SAMSUNG GT-19308 4.3 和 ios8.4
      原生浏览器和safari 可以
      UC浏览器都 可以

    ios7.0 safri 和 UC浏览器 都不可以

    4. 注意:若给 html 根元素绑定了
    $('html').on('touchend', function(){ e.preventDefault(); })
    则页面里所有的元素 click 绑定的事件都触发不了, input 都不能点击输入了。

  • 相关阅读:
    array with objects sort
    Vue组件之区域滚动
    ajax跨域请求问题总结
    常见contentType
    Sublime Text 3实用快捷键大全
    具有层级关系的扁平化数组转化成树形结构数组
    阿里云地图选择器
    前端解析二进制文件流并下载
    tool.js日常工具方法
    git操作
  • 原文地址:https://www.cnblogs.com/zhengming2016/p/5567471.html
Copyright © 2011-2022 走看看