mirror of https://github.com/layui/layui
优化 carousel 移动端滑动切换
parent
bc6da28612
commit
462ed13f18
|
@ -331,14 +331,28 @@ layui.define(['jquery', 'lay'], function(exports){
|
||||||
if(options.elem.data('haveEvents')) return;
|
if(options.elem.data('haveEvents')) return;
|
||||||
|
|
||||||
// 移入移出容器
|
// 移入移出容器
|
||||||
options.elem.on('mouseenter', function(){
|
options.elem.on('mouseenter touchstart', function(){
|
||||||
if (that.config.autoplay === 'always') return;
|
if (that.config.autoplay === 'always') return;
|
||||||
clearInterval(that.timer);
|
clearInterval(that.timer);
|
||||||
}).on('mouseleave', function(){
|
}).on('mouseleave touchend', function(){
|
||||||
if (that.config.autoplay === 'always') return;
|
if (that.config.autoplay === 'always') return;
|
||||||
that.autoplay();
|
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);
|
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 元素操作
|
* lay 元素操作
|
||||||
|
|
Loading…
Reference in New Issue