zoukankan      html  css  js  c++  java
  • 移动端touch模块

    在自己写touch事件时,总是会出现各种各样的bug,正好发现zepto的touch模块,很好用,而且由于zepto和jquery语法的相似性,这个模块也可以直接引用到jquery中,

    得花时间好好消化一番,这样以后自己就可以随心所欲了。。。

    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) {//IE10中新加入的对高级用户输入的识别支持
    gesture = new MSGesture() //实例手势对象
    gesture.target = document.body
    }
    
    $(document)
    .bind('MSGestureEnd', function(e){ //类似mouseup,兼容触屏和鼠标操作
    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中Class对象详解和类名.class, class.forName(), getClass()区别
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    107. Binary Tree Level Order Traversal II
    109. Convert Sorted List to Binary Search Tree
    108. Convert Sorted Array to Binary Search Tree
    110. Balanced Binary Tree
    STL容器迭代器失效问题讨论
    113. Path Sum II
    112. Path Sum
  • 原文地址:https://www.cnblogs.com/mopagunda/p/4883945.html
Copyright © 2011-2022 走看看