mirror of https://github.com/layui/layui
优化 carousel 移动端滑动切换
parent
bc6da28612
commit
462ed13f18
|
@ -331,13 +331,27 @@ layui.define(['jquery', 'lay'], function(exports){
|
|||
if(options.elem.data('haveEvents')) return;
|
||||
|
||||
// 移入移出容器
|
||||
options.elem.on('mouseenter', function(){
|
||||
options.elem.on('mouseenter touchstart', function(){
|
||||
if (that.config.autoplay === 'always') return;
|
||||
clearInterval(that.timer);
|
||||
}).on('mouseleave', function(){
|
||||
}).on('mouseleave touchend', function(){
|
||||
if (that.config.autoplay === 'always') return;
|
||||
that.autoplay();
|
||||
});
|
||||
|
||||
var touchEl = options.elem;
|
||||
var isVertical = options.anim === 'updown';
|
||||
lay.touchSwipe(touchEl, {
|
||||
onTouchEnd: function(e, state){
|
||||
var duration = Date.now() - state.timeStart;
|
||||
var delta = isVertical ? state.deltaY : state.deltaX;
|
||||
var speed = delta / duration;
|
||||
var shouldSwipe = Math.abs(speed) > 0.25 || Math.abs(delta) > touchEl[isVertical ? 'height' : 'width']() / 3;
|
||||
if(shouldSwipe){
|
||||
that.slide(delta > 0 ? '' : 'sub');
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
options.elem.data('haveEvents', true);
|
||||
};
|
||||
|
|
|
@ -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 元素操作
|
||||
|
|
Loading…
Reference in New Issue