鲜荣彬
Herry

1、像素知识

  px: css pixels,逻辑像素,浏览器使用的抽象单位

  dp,pt:device independent pixels ,设备无关像素

  dpr:devicePixelRatio 设备像素缩放比

  

  计算公司:1px=(dpr)*dpr*dp

2、Viewport

  手机浏览器默认为我们做了两件事。

    一:页面渲染在一个980px(iso)的Viewport。

    二:缩放

  是有 visual Viewport 与 layout viewport.

  最佳meta设置如下:

  <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">

  window.innerWidth/document.body.clientWidth=缩放比

  【布局Viewport】=【设备宽度】=【度量Viewport】

3、Tap基础事件

  自定义Tap事件原理:

  在touchstart、touchend时记录时间、手指位置,在touchend时进行比较,如果手指位置为同一位置(或允许移动一个非常小的位移值),

  且事件间隔较短(一般认为是200ms),且过程中未触发过touchmove,即可认为触发了手持设备的"click",一般称为"tap"。

 

  Tap透传Bug

  解决方案:

  1、使用缓动动画,过渡300ms延迟。

  2、中间层dom元素的加入,让中间层接受这个“穿透”事件,稍后隐藏。

  3、上下都使用"tap"事件。

 

四、Touch 基础事件

  touchstart、touchmove、touchend、touchcancel(系统取消touch时触发)。

  Bug:

    Android只会触发一次touchstart,一次touchmove,touchend不触发。

  在 touchmove中加入:event.preventDefault(),但会导致默认行为不发生,比如scroll。

  触摸板上下左右滑动事例:

<style>
    .touchpad{
        width: 100%;
        height: 200px;
        font-size: 40px;
        text-align: center;
        line-height: 200px;
        background: rgba(0,0,0,0.5);
        position: relative;
        color: #ddd;
    }

    .ball{
        display: none;
        position: absolute;
        width: 25px;
        height: 25px;
        border-radius: 15px;
        background-color: #7AE6FF;
        top: 0;
        left: 0;
    }
    p{
        height: 30px;
    }

</style>
</head>
<body>

<p id="desc"></p>
<div id="touchPad" class="touchpad">触摸板</div>
<div id="ball" class="ball"></div>

<script src="../js/zepto.js"></script>
<script type="text/javascript">
    var touchpad = document.querySelector('#touchPad'),
        ball = document.querySelector('#ball'),
        desc = document.querySelector('#desc');


    //获取touch的点(兼容mouse事件)
    var getTouchPos = function(e){
        var touches = e.touches;
        if(touches && touches[0]) {
            return { x : touches[0].clientX ,
                     y : touches[0].clientY };
        }
        return { x : e.clientX , y: e.clientY };
    }

    //计算两点之间距离
    var getDist = function(p1 , p2){
        if(!p1 || !p2) return 0;
        return Math.sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
    }
    //计算两点之间所成角度
    var getAngle = function(p1 , p2){
        var r = Math.atan2(p2.y - p1.y, p2.x - p1.x);
        var a = r * 180 / Math.PI;
        return a;
    };
     //获取swipe的方向
    var getSwipeDirection = function(p2,p1){
        var dx = p2.x - p1.x;
        var dy = -p2.y + p1.y;    
        var angle = Math.atan2(dy , dx) * 180 / Math.PI;

        if(angle < 45 && angle > -45) return "right";
        if(angle >= 45 && angle < 135) return "top";
        if(angle >= 135 || angle < -135) return "left";
        if(angle >= -135 && angle <= -45) return "bottom";

    }


    var startEvtHandler = function(e){
        var pos = getTouchPos(e);
        ball.style.left = pos.x + 'px';
        ball.style.top = pos.y + 'px';
        ball.style.display = 'block';

        var touches = e.touches; 
        if( !touches || touches.length == 1 ){ //touches为空,代表鼠标点击
            point_start = getTouchPos(e);
            time_start = Date.now();
        }
    }

    var moveEvtHandler = function(e){
        var pos = getTouchPos(e);
        ball.style.left = pos.x + 'px';
        ball.style.top = pos.y + 'px';


        point_end = getTouchPos(e);
        e.preventDefault();
    }

    //touchend的touches和targetTouches没有对象,只有changeTouches才有
    var endEvtHandler = function(e){
        ball.style.display = 'none';

        var time_end = Date.now();

        //距离和时间都符合
        if(getDist(point_start,point_end) > SWIPE_DISTANCE && time_start- time_end < SWIPE_TIME){
           
           var dir = getSwipeDirection(point_end,point_start);
           touchPad.innerHTML = 'swipe'+dir;
        }
    }

   
    var SWIPE_DISTANCE = 30;  //移动30px之后才认为swipe事件
    var SWIPE_TIME = 500;     //swipe最大经历时间
    var point_start,
        point_end,
        time_start,
        time_end;

    //判断是PC或者移动设备
    var startEvt, moveEvt, endEvt;
    if("ontouchstart" in window){
        startEvt="touchstart";
        moveEvt="touchmove";
        endEvt="touchend";
    }else{
        startEvt="mousedown";
        moveEvt="mousemove";
        endEvt="mouseup";            
    }

    touchpad.addEventListener(startEvt, startEvtHandler);
    touchpad.addEventListener(moveEvt, moveEvtHandler);
    touchpad.addEventListener(endEvt, endEvtHandler);



</script>

</body>

 

  

posted on 2016-12-12 23:01  Herry彬  阅读(222)  评论(0编辑  收藏  举报