|
|
@ -505,6 +505,110 @@
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 检测是否支持 Passive Event Listeners
|
|
|
|
|
|
|
|
* 引用自 https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
|
|
|
|
|
|
|
|
* @type {boolean}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
lay.passiveSupported = function(){
|
|
|
|
|
|
|
|
var passiveSupported = false;
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
var opts = Object.defineProperty({}, 'passive', {
|
|
|
|
|
|
|
|
get: function() {
|
|
|
|
|
|
|
|
passiveSupported = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
window.addEventListener('test', null, opts);
|
|
|
|
|
|
|
|
window.removeEventListener('test', null, opts);
|
|
|
|
|
|
|
|
} catch (err) {}
|
|
|
|
|
|
|
|
return passiveSupported;
|
|
|
|
|
|
|
|
}();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 是否支持 touch 事件
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
lay.touchEventsSupported = function(){
|
|
|
|
|
|
|
|
return 'ontouchstart' in window;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @typedef touchSwipeState
|
|
|
|
|
|
|
|
* @prop {{x: number,y: number}} coordsStart - 初始坐标
|
|
|
|
|
|
|
|
* @prop {{x: number,y: number}} coordsEnd - 结束坐标
|
|
|
|
|
|
|
|
* @prop {number} deltaX - X 轴变化量
|
|
|
|
|
|
|
|
* @prop {number} deltaY - Y 轴变化量
|
|
|
|
|
|
|
|
* @prop {'none'|'right'|'left'|'up'|'down'} direction - 滑动方向
|
|
|
|
|
|
|
|
* @prop {Date} timeStart 开始时间
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @callback touchSwipeCallback
|
|
|
|
|
|
|
|
* @param {TouchEvent} e 滑动事件
|
|
|
|
|
|
|
|
* @param {touchSwipeState} state 滑动相关的状态
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 基于 touch 事件的触摸滑动
|
|
|
|
|
|
|
|
* @param {string | HTMLElement | JQuery} elem - HTML 元素
|
|
|
|
|
|
|
|
* @param {{onTouchStart?: touchSwipeCallback, onTouchMove?: touchSwipeCallback, onTouchEnd?: touchSwipeCallback}} opts - 配置项
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
lay.touchSwipe = function(elem, opts){
|
|
|
|
|
|
|
|
var options = opts
|
|
|
|
|
|
|
|
var targetElem = lay(elem)[0];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!targetElem || !lay.touchEventsSupported()) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var state = {
|
|
|
|
|
|
|
|
coordsStart: {x:0, y:0},
|
|
|
|
|
|
|
|
coordsEnd: {x:0, y:0},
|
|
|
|
|
|
|
|
deltaX: 0,
|
|
|
|
|
|
|
|
deltaY: 0,
|
|
|
|
|
|
|
|
direction:'none', // 'up','down','left','right','none
|
|
|
|
|
|
|
|
timeStart: null
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var onStart = function(e){
|
|
|
|
|
|
|
|
if(e.touches.length !== 1) return;
|
|
|
|
|
|
|
|
bindEvents();
|
|
|
|
|
|
|
|
state.timeStart = Date.now();
|
|
|
|
|
|
|
|
state.coordsStart.x = state.coordsEnd.x = e.touches[0].clientX;
|
|
|
|
|
|
|
|
state.coordsStart.y = state.coordsEnd.y = e.touches[0].clientY;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
options.onTouchStart && options.onTouchStart(e, state);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var onMove = function(e){
|
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
|
|
|
state.coordsEnd.x = e.touches[0].clientX;
|
|
|
|
|
|
|
|
state.coordsEnd.y = e.touches[0].clientY;
|
|
|
|
|
|
|
|
state.deltaX = state.coordsStart.x - state.coordsEnd.x;
|
|
|
|
|
|
|
|
state.deltaY = state.coordsStart.y - state.coordsEnd.y;
|
|
|
|
|
|
|
|
if(Math.abs(state.deltaX) > Math.abs(state.deltaY)){
|
|
|
|
|
|
|
|
state.direction = state.deltaX > 0 ? 'left' : 'right';
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
state.direction = state.deltaY > 0 ? 'up' : 'down';
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
options.onTouchMove && options.onTouchMove(e, state);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var onEnd = function(e){
|
|
|
|
|
|
|
|
options.onTouchEnd && options.onTouchEnd(e, state);
|
|
|
|
|
|
|
|
unbindEvents();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var bindEvents = function(){
|
|
|
|
|
|
|
|
targetElem.addEventListener('touchmove', onMove, lay.passiveSupported ? { passive: false} : false);
|
|
|
|
|
|
|
|
targetElem.addEventListener('touchend', onEnd);
|
|
|
|
|
|
|
|
targetElem.addEventListener('touchcancel', onEnd);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var unbindEvents = function(){
|
|
|
|
|
|
|
|
targetElem.removeEventListener('touchmove', onMove);
|
|
|
|
|
|
|
|
targetElem.removeEventListener('touchend', onEnd, lay.passiveSupported ? { passive: false} : false);
|
|
|
|
|
|
|
|
targetElem.removeEventListener('touchcancel', onEnd);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
targetElem.addEventListener('touchstart', onStart);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* lay 元素操作
|
|
|
|
* lay 元素操作
|
|
|
|