美文网首页
移动端事件

移动端事件

作者: llpy | 来源:发表于2017-01-12 09:02 被阅读663次

    移动端的常见事件

    touchstart 手指按下时触发
    touchmove 手指移动
    touchend 手指抬起

    <div></div>
    <p></p>
    <script>
    
    var oDiv = document.querySelector('div');
    var oP = document.querySelector('p');
    
    //最好不要用on的方式, 在chrome 模拟器下时好时坏
    oDiv.addEventListener('touchstart', function(){
        oP.innerHTML += '按下';
    }, false);
    
    oDiv.addEventListener('touchmove', function(){
        oP.innerHTML += '移动';
    }, false);
    
    oDiv.addEventListener('touchend', function(){
        oP.innerHTML += '抬起';
    }, false);
    </script>
    

    pc端的事件在移动端的问题

    pc上的事件比移动端的事件略慢, 大概在300ms左右

    oDiv.addEventListener('mouseup', function(){
        oP.innerHTML += '鼠标抬起 ';
    }, false);
    
    oDiv.addEventListener('touchend', function(){
        oP.innerHTML += '抬起 ';
    }, false);
    

    每次点击, 都是抬起 鼠标抬起

    注意不要:移动手指, 移动之后就不会触发mouseup事件了

    移动端的点透

    <style>
    div{
        height: 200px;
        width: 200px;
        background: rgba(99, 99, 99, 0.5);
        position: absolute;
        top: 0;
    }
    </style>
    <span>span, 点击我</span>
    
    <div>
    <script>
    var oDiv = document.querySelector('div');
    var oSpan = document.querySelector('span');
    
    
    oDiv.addEventListener('touchend', function(){
        this.style.display = 'none';
    }, false);
    
    oSpan.addEventListener('click', function(){
        alert(1);
    }, false);
    
    </script>
    

    效果是点击div,手指抬起div消失

    但是,当你点到div上span标签的位置,会触发span的click事件,div是覆盖了span标签的

    span标签应该是点不到的, 如果将div的背景设为实色, 根本就看不到span标签

    这就是移动端的点透问题:

    当两个元素重叠时,当上层元素发生点击, 并且下层元素也有点击(焦点)特性,
    如果在300ms之内, 上层元素消失, 目标点就会到下层元素, 触发下层元素的点击行为

    所以如果你点击div300毫秒之后才抬起手指, 也不会触发span的click事件

    原因就是因为pc上的事件比移动端的事件的300ms延迟

    关于a标签,也会发生上面的点透问题

    <style>
    div{
        height: 200px;
        width: 200px;
        background: rgba(99, 99, 99, 0.5);
        position: absolute;
        top: 0;
    }
    </style>
    <a href="/">a标签</a>
    
    <div>
    <script>
    var oDiv = document.querySelector('div');
    
    
    oDiv.addEventListener('touchend', function(){
        this.style.display = 'none';
    }, false);
    
    
    </script>
    

    解决办法

    1. 换成移动端事件
     oSpan.addEventListener('touchend', function(){
        alert(1);
    }, false);
    
    1. 阻止pc的事件
    
    //猜想(pc的事件应该都算默认行为) 
    document.addEventListener('touchstart', function(ev){
        ev.preventDefault();
    }, false);
    

    这是你注册的click事件, 永远都不会触发, a标签也不会跳转,

    touch所有类型事件都会冒泡,如果阻止了touchstart的默认行为,后续的mousedown和click事件将不会触发

    阻止了touchmove的默认行为,后续的mousemove事件将不会触发

    如果阻止了touchend的默认行为,后续的mouseup和click事件将不会触发

    同时解决了:

    1. IOS10下设置meta禁止用户缩放是不可行的。(使用阻止pc事件就可以在IOS10下禁止用户缩放)

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

    3. 禁止系统默认的滚动条、阻止橡皮筋效果

    4. 禁止长按选中文字、选中图片、系统默认菜单

    5. 解决点透问题

    6. 也阻止了焦点元素的焦点行为(要正常使用:ev.stopPropagation()阻止冒泡)

    移动端的事件对象

    touchs

    当前位于屏幕上的所有手指的一个列表

    targetTouches

    位于当前DOM元素上的手指的一个列表

    changedTouches

    涉及当前事件的手指的一个列表

    <style>
    div{
        height: 100px;
        width: 100px;
        background: red;
    }
    </style>
    <div></div>
    <script>
    var div = document.querySelector('div');
    div.addEventListener('touchmove', function(ev){
        //只要我有几个手指在屏幕上, 就会显示几
        // div.innerHTML = ev.touches.length;
        
    
    })
    </script>
    

    例子:轮播图

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <style>
    *{
        margin: 0;
        padding: 0;
    }
    .container{
        width: 100%;
        height: 321px;
        overflow: hidden;
        position: relative;
    
    }
    .wrap{
        position: absolute;
        width: 100%;
        white-space: nowrap;
        font-size: 0;
        left: 0;
    }
    
    img{
        width: 100%;
        display: inline-block;
    }
    </style>
    </head>
    <body>
    <div class="container">
        <div class="wrap">
            ![](1.jpg)
            ![](2.jpg)
            ![](3.jpg)
            ![](4.jpg)
        </div>
    
    </div>
    <script>
    document.addEventListener('touchstart', function(ev){
        ev.preventDefault();
    })
    var wrap = document.querySelector('.wrap');
    var img = document.querySelector('img');
    
    var width = img.offsetWidth;
    
    wrap.addEventListener('touchstart', function(ev){
    
        // 需要去掉过渡效果,因为会跟移动产生冲突,造成卡顿
        wrap.style.transition = 'none';
        //移动端只需加webkit前缀
        wrap.style.webkitTransition = 'none';
    
    
        var e = ev.changedTouches[0];
        var disX = e.pageX;
        var left = this.offsetLeft;
        
    
        wrap.addEventListener('touchmove', function(ev){
            var e = ev.changedTouches[0];
            this.style.left = left + (e.pageX - disX) + 'px';
        });
    
        wrap.addEventListener('touchend', function(ev){
            var e = ev.changedTouches[0];
    
            
            left = this.offsetLeft;
            var num = Math.round(left/width);
    
            wrap.style.transition = '1s';
            //移动端只需加webkit前缀
            wrap.style.webkitTransition = '1s';
            wrap.style.left = num*width+'px';
    
        })
    });
    </script>
    </body>
    </html>
    

    无缝滚动, 复制相同的img, 如果你本来有4张图片, 那么现在就有8张

    如果点toucnstart到第一张, 迅速跳的第5张, 如果点toucnstart到第8张, 迅速跳的第4张,

    wrap.addEventListener('touchstart', function(ev){
        ....
        num = Math.round(left/width);
        if(num==0){
            num = -length;
        }
        if(-num==2*length-1){
            num = -(length-1);
        }
    
        this.style.left = num*width + 'px';
        left = this.offsetLeft;
        ....
    })
    

    相关文章

      网友评论

          本文标题:移动端事件

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