【精华分享】layui.carousel轮播组件实现移动端手势左右滑动效果

分享 未结 精帖
16 3429
Kandy
Kandy 2018-6-1
悬赏:20飞吻
发现很多人不用layui.carousel轮播组件的原因之一,就是它竟然没有支持广泛应用的手势滑动效果,只有开关两个左右箭头图标,效果不是很好。
同事为此也困惑许久,谁让我们坚持用这个又爱又恨的Layer呢?(别打脸 >_<)没办法,我也等不到作者何年何日再更新了,只能自己亲自操刀了~

【第一步:实现触发事件】
在移动端,手势左右滑动,是很普遍的用户行为。
早些年前,(多数懒人)一直是用的jQuery Mobile中的swipe(滑动),swipeleft(左滑),swiperight(右滑),效果确实很好。但现在,我们自己也来写一个:
1)核心事件
touchstart:手指【触碰】屏幕时触发
touchmove:手指【移动】屏幕时触发
touchend:手指【离开】屏幕时触发
2)获取坐标
touches[i]: 当前屏幕上所有触摸点的列表;(只能用于touchstart和touchmove中)
targetTouches[i]: 当前对象上所有触摸点的列表;(只能用于touchstart和touchmove中)
changedTouches[i]: 涉及当前(引发)事件的触摸点的列表(只能用于touchmove和touchend中)

注1)i表示第i个手指,从0开始。一般多用单指(滑动)或双指(缩放)操作,请勿轻易尝试3指及以上操作!
注2)JS使用时前缀为【e.*】;而JQuery使用时前缀为【e.originalEvent.*】

3)代码实例(JQuery)
$("#layui_carousel").on("touchstart", function (e) {
var startX = e.originalEvent.targetTouches[0].pageX;//开始坐标X
$(this).on('touchmove', function (e) {
arguments[0].preventDefault();//阻止手机浏览器默认事件
});
$(this).on('touchend', function (e) {
var endX = e.originalEvent.changedTouches[0].pageX;//结束坐标X
e.stopPropagation();//停止DOM事件逐层往上传播
//alert("开始滑动" + startX + "到" + endX);
if (endX - startX > 30) {
alert("向右滑动");
}
else if (startX - endX > 30) {
alert("向左滑动");
}
$(this).off('touchmove touchend');
});
});
【第二步:找到触发内容】
多数人的困惑应该就是这步了,没错,官方文档写的太简单了(一贯做法)。通过查看了carousel.js的源码,我们发现核心代码是这样的:
//箭头
Class.prototype.arrow = function(){
var that = this
,options = that.config;

//模板
var tplArrow = $([
'<button class="layui-icon '+ ELEM_ARROW +'" lay-type="sub">'+ (options.anim === 'updown' ? '' : '') +'</button>'
,'<button class="layui-icon '+ ELEM_ARROW +'" lay-type="add">'+ (options.anim === 'updown' ? '' : '') +'</button>'
].join(''));

//预设基础属性
options.elem.attr('lay-arrow', options.arrow);

//避免重复插入
if(options.elem.find('.'+ELEM_ARROW)[0]){
options.elem.find('.'+ELEM_ARROW).remove();
};
options.elem.append(tplArrow);

//事件
tplArrow.on('click', function(){
var othis = $(this)
,type = othis.attr('lay-type')
that.slide(type);
});
};
当触发了that.slide(“sub”)就表示滑动到上一个;
当触发了that.slide(“add”)就表示滑动到下一个;

那么问题又来了,that是什么呢?
that就是轮播组件对象!我们已经会通过carousel.render({……})来配置轮播组件,那么该方法返回的就是当前实例的对象!
var ins;
layui.use(['carousel', 'form'], function () {
var carousel = layui.carousel;
ins = carousel.render({
elem: '#layui_carousel'
, width: '100%'
, height: '5rem'
, interval: 4000
, arrow: 'none' //始终不显示箭头
});
});
以上代码通过变量ins,就把这个that给揪出来了[嘻嘻]

【第三步:完整代码分享】
HTML里主要就是一个ID为layui_carousel的div,所以这里就分享JS代码了:
var ins;
layui.use(['carousel', 'form'], function () {
var carousel = layui.carousel;
ins = carousel.render({
elem: '#layui_carousel'
, width: '100%'
, height: '5rem'
, interval: 4000
, arrow: 'none' //始终不显示箭头
});
});
$("#layui_carousel").on("touchstart", function (e) {
var startX = e.originalEvent.targetTouches[0].pageX;//开始坐标X
$(this).on('touchmove', function (e) {
arguments[0].preventDefault();//阻止手机浏览器默认事件
});
$(this).on('touchend', function (e) {
var endX = e.originalEvent.changedTouches[0].pageX;//结束坐标X
e.stopPropagation();//停止DOM事件逐层往上传播
if (endX - startX > 30) {
ins.slide("sub");
}
else if (startX - endX > 30) {
ins.slide("add");
}
$(this).off('touchmove touchend');
});
});
回帖