zoukankan      html  css  js  c++  java
  • Zepto.js touch,tap增加 touch模块深入分析

    1、 touch库实现了什么和引入背景

    click事件在移动端上会有 300ms 的延迟,同时因为需要 长按 , 双触击 等富交互,所以我们通常都会引入类似 zepto 这样的库。zepto 中touch库实现了 'swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap' 这样一些功能。

    2、touch库实现'swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'重要源代码(绑定在touchend事件上)

    处理Touch事件能让你了解到用户的每一根手指的位置,在touch事件触发的时候产生,可以通过touch event handler的event对象取到,如果基于zepto.js开发,一般是通过event.touches[0]来获取属性。

    重要属性

    • clientX、clientY:触摸点相对于浏览器窗口viewport的位置
    • pageX、pageY: 触摸点相对于页面的位置
    • screenX,screenY:触摸点相对于屏幕的位置
    • identifier:touch:对象的unique ID

    你可以绑定以下四种Touch事件来了解基本的touch事件:

    • touchstart:手指触摸屏幕上的时候触发
    • touchmove:手指在屏幕上移动的时候触发
    • touchend:手指从屏幕上拿起的时候触发
    • touchcancel:系统取消touch事件的时候触发

    Touch模块添加以下事件,可以使用 on 和 off 来绑定。

    • tap —元素tap的时候触发。
    • singleTap and doubleTap — 这一对事件可以用来检测元素上的单击和双击。(如果你不需要检测单击、双击,使用 tap 代替)。
    • longTap — 当一个元素被按住超过750ms触发。
    • swipeswipeLeftswipeRightswipeUpswipeDown — 当元素被划过时触发。(可选择给定的方向)

    这些事件也是所有Zepto对象集合上的快捷方法。

    操作说明

    当你触摸屏幕并抬起手指,只触发touchstart和touched,当如果手指触摸屏幕并移动后抬起会触发touchstart,多次touchmove,touchend或touchcanel,可以根据基本的touch事件来封装成你想要实现复杂的效果,比如向左或向右滑动,向上或向下滑动,并在滑动时封装你想实现的效果。

    touch.js封装好了滑动事件的处理,将其添加到自己的项目中,就可以直接调用向右、右、上、下滑动的事件。这样zepto.js官网手册中的例子就可以正常运行了。

    使用示例

    <style>.delete { display: none; }</style>
    <ul id=items>
      <li>List item 1 <span class=delete>DELETE</span></li>
      <li>List item 2 <span class=delete>DELETE</span></li>
    </ul>
    
    <script>
    // show delete buttons on swipe
    $('#items li').swipe(function(){
      $('.delete').hide()
      $('.delete', this).show()
    })
    // delete row on tapping delete button
    $('.delete').tap(function(){
      $(this).parent('li').remove()
    })
    </script>
    官网下载下来的zepto.js在后面新增下面代码

    ;
    (function($) {
    var touch = {},
    touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
    longTapDelay = 750,
    gesture
    function swipeDirection(x1, x2, y1, y2) {
    return Math.abs(x1 - x2) >=
    Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
    }
    function longTap() {
    longTapTimeout = null
    if (touch.last) {
    touch.el.trigger('longTap')
    touch = {}
    }
    }
    function cancelLongTap() {
    if (longTapTimeout) clearTimeout(longTapTimeout)
    longTapTimeout = null
    }
    function cancelAll() {
    if (touchTimeout) clearTimeout(touchTimeout)
    if (tapTimeout) clearTimeout(tapTimeout)
    if (swipeTimeout) clearTimeout(swipeTimeout)
    if (longTapTimeout) clearTimeout(longTapTimeout)
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
    touch = {}
    }
    function isPrimaryTouch(event) {
    return (event.pointerType == 'touch' ||
    event.pointerType == event.MSPOINTER_TYPE_TOUCH) && event.isPrimary
    }
    function isPointerEventType(e, type) {
    return (e.type == 'pointer' + type ||
    e.type.toLowerCase() == 'mspointer' + type)
    }
    $(document).ready(function() {
    var now, delta, deltaX = 0,
    deltaY = 0,
    firstTouch, _isPointerType
    if ('MSGesture' in window) {
    gesture = new MSGesture()
    gesture.target = document.body
    }
    $(document)
    .bind('MSGestureEnd', function(e) {
    var swipeDirectionFromVelocity =
    e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null;
    if (swipeDirectionFromVelocity) {
    touch.el.trigger('swipe')
    touch.el.trigger('swipe' + swipeDirectionFromVelocity)
    }
    })
    .on('touchstart MSPointerDown pointerdown', function(e) {
    if ((_isPointerType = isPointerEventType(e, 'down')) && !isPrimaryTouch(e)) return
    firstTouch = _isPointerType ? e : e.touches[0]
    if (e.touches && e.touches.length === 1 && touch.x2) {
    // Clear out touch movement data if we have it sticking around
    // This can occur if touchcancel doesn't fire due to preventDefault, etc.
    touch.x2 = undefined
    touch.y2 = undefined
    }
    now = Date.now()
    delta = now - (touch.last || now)
    touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode)
    touchTimeout && clearTimeout(touchTimeout)
    touch.x1 = firstTouch.pageX
    touch.y1 = firstTouch.pageY
    if (delta > 0 && delta <= 250) touch.isDoubleTap = true
    touch.last = now
    longTapTimeout = setTimeout(longTap, longTapDelay)
    // adds the current touch contact for IE gesture recognition
    if (gesture && _isPointerType) gesture.addPointer(e.pointerId);
    })
    .on('touchmove MSPointerMove pointermove', function(e) {
    if ((_isPointerType = isPointerEventType(e, 'move')) && !isPrimaryTouch(e)) return
    firstTouch = _isPointerType ? e : e.touches[0]
    cancelLongTap()
    touch.x2 = firstTouch.pageX
    touch.y2 = firstTouch.pageY
    deltaX += Math.abs(touch.x1 - touch.x2)
    deltaY += Math.abs(touch.y1 - touch.y2)
    })
    .on('touchend MSPointerUp pointerup', function(e) {
    if ((_isPointerType = isPointerEventType(e, 'up')) && !isPrimaryTouch(e)) return
    cancelLongTap()
    // swipe
    if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
    (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
    swipeTimeout = setTimeout(function() {
    touch.el.trigger('swipe')
    touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
    touch = {}
    }, 0)
    // normal tap
    else if ('last' in touch)
    // don't fire tap when delta position changed by more than 30 pixels,
    // for instance when moving to a point and back to origin
    if (deltaX < 30 && deltaY < 30) {
    // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
    // ('tap' fires before 'scroll')
    tapTimeout = setTimeout(function() {
    // trigger universal 'tap' with the option to cancelTouch()
    // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
    var event = $.Event('tap')
    event.cancelTouch = cancelAll
    touch.el.trigger(event)
    // trigger double tap immediately
    if (touch.isDoubleTap) {
    if (touch.el) touch.el.trigger('doubleTap')
    touch = {}
    }
    // trigger single tap after 250ms of inactivity
    else {
    touchTimeout = setTimeout(function() {
    touchTimeout = null
    if (touch.el) touch.el.trigger('singleTap')
    touch = {}
    }, 250)
    }
    }, 0)
    } else {
    touch = {}
    }
    deltaX = deltaY = 0
    })
    // when the browser window loses focus,
    // for example when a modal dialog is shown,
    // cancel all ongoing events
    .on('touchcancel MSPointerCancel pointercancel', cancelAll)
    // scrolling the window indicates intention of the user
    // to scroll, not tap or swipe, so cancel all ongoing events
    $(window).on('scroll', cancelAll)
    })
    ;
    ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
    'doubleTap', 'tap', 'singleTap', 'longTap'
    ].forEach(function(eventName) {
    $.fn[eventName] = function(callback) {
    return this.on(eventName, callback)
    }
    })
    })(Zepto)

    效果就实现了

     
  • 相关阅读:
    java—数组乘积输入: 一个长度为n的整数数组input 输出: 一个长度为n的数组result,满足result[i] = input数组中,除了input[i] 之外的所有数的乘积,不用考虑溢出例如 input {2, 3, 4, 5} output: {60, 40, 30, 24}
    深入理解按位异或运算符
    针对数组的三中排序方式:冒泡排序,选择排序,插入排序
    笔试题目整理
    Android中AIDL通信机制分析
    android消息处理机制之2handler与looper,MessageQueue:的关系
    Android消息处理机制(Handler 与Message)---01
    vim 批处理
    React 组件条件渲染的几种方式
    vim命令行模式
  • 原文地址:https://www.cnblogs.com/0liaoyi/p/6110505.html
Copyright © 2011-2022 走看看