移动端常用事件 属性 点击穿透问题的解决方案

移动端事件

在前端的移动web开发中,有一部分事件只在移动端产生,如触摸touch相关的事件,以下是关于移动端事件的小结

1.PC端事件在移动端的兼容问题

1.1 click事件的200~300ms延迟问题

主要原因是,需要双击来放大H5页面,会等待200~300ms来看看是否会点击第二次,来判断是否放大
由于双击缩放功能的存在,click事件触发会有200~300ms的延迟

1.2 dbclick事件失效

双击缩放功能的存在,PC端的dbclick事件也就失效了

2.移动端特有的touch事件

2.1 touch事件与click事件同时触发

touchStart---->touchend----->click(200ms~300ms)
通过e.preventDefault来阻止鼠标的点击事件

2.2 touchstart事件

一点击就触发

<body>
    <div>
        touch mobile
    </div>
    <script>
        document.querySelector("div").addEventListener("touchstart",(e)=>{
            console.log(e.type);
        });
    </script>
</body>

2.3 touchmove事件

在实际开发中事件执行的频率非常高,会多次重复触发,移动端的计算资源非常宝贵,需要考虑事件的节流
移出事件的目标对象区域的时候,touchmove依然在执行

<body>
    <div style="width: 100%;height: 150px;background-color: salmon;">
        <p></p>
    </div>
    <script>
        var i = 1;
        document.querySelector("div").addEventListener("touchmove", (e) => {
            document.querySelector("p").innerHTML = "touchmove: " + e.currentTarget.tagName + ',' + i++;
        });
    </script>
</body>

2.4 touchend

当手指离开触摸屏时触发
不管在何处离开,touchend的target始终保持不变,即使已经移出了区域

<body>
    <div style="width: 100%;height: 150px;background-color: salmon;">
        <p></p>
    </div>
    <script>
        var i = 1;
        document.querySelector("div").addEventListener("touchmove", (e) => {
            document.querySelector("p").innerHTML = "touchmove: " + e.currentTarget.tagName + ',' + i++;
        });

        //touchend
        document.querySelector("div").addEventListener("touchend", (e) => {
            console.log(e.type);
        });
    </script>
</body>

2.5 touchcancel

touchcancel什么时候执行?手指离开屏幕不会触发该事件
模态对话框,被意外的情况打断,比如打手机游戏时突然打进电话,那么该事件就会触发,游戏内的touch失效

2.6 触摸事件

通过打印e输出里面的一些事件信息

2.7 TouchList

如果用户的三指触摸屏幕,与之相关的每根手指都会生成touch对象,共有3个
TouchList里面是touch对象,TouchList是类数组

<body>
    <div style="width: 100%;height: 150px;background-color: salmon;">
        <p></p>
    </div>
    <script>
        document.querySelector("div").addEventListener("touchend", (e) => {
            console.log(Array.isArray(e.changedTouches));
            //返回touch对象的个数
            document.querySelector("p").innerHTML = e.changedTouches.length;
            for(let i = 0; i <e.changedTouches.length; i++){
                console.log(e.changedTouches.item(i));
            }
        });
    </script>
</body>

2.8 Touch对象

identifier: 0 //每一个touch对象的唯一标识,通过它追踪每一个touch对象
screenX: 297.6000061035156 ////相对于屏幕
screenY: 302.3999938964844
clientX: 171.76470947265625 //相对于viewport的左边缘,不包含滚动条
clientY: 75
pageX: 171.76470947265625 //相对于document左边缘,会包含滚动条
pageY: 75
radiusX: 16.91176414489746 //半径
radiusY: 16.91176414489746
rotationAngle: 0 //角度
force: 0 //力度
target: div //DOM对象
proto: Touch

3 触摸手势封装相关的框架及事件

手势相关的事件一般就是tap类(触屏)和滑动(swiper)

4 移动端点击穿透问题

4.1 点击穿透问题

点击遮罩层(mask,也要蒙层)上的关闭按钮,蒙层消失后发现触发了按钮下main元素的click事件
原因:主要是touch和click同时存在,touch之后又触发了click

解决方案:

  1. 只用touch
    既然是由于touch之后的click造成的,那么不用click自然解决了这个问题
    需要注意a标签的href也是click,需要换成JavaScript:void(0)
  2. 只用click
    下下策,因为300ms延迟,如果交互性要求不高可以这么做,但快一点总归是好的
  3. 拿个东西来挡住
    比较笨的办法,不推荐用
  4. tap延迟350ms再隐藏mask
    改动最小,缺点是隐藏mask变慢了
  5. pointer-eventer
    有缺陷,不建议使用
posted @ 2020-03-23 09:02  IslandZzzz  阅读(709)  评论(0编辑  收藏  举报