有时候我们在一个list中要为列表项添加左右滑动的效果,通过滑动出来的按钮实现一些点击事件,这时候就可以用到本文所介绍的插件了。
照例,先上效果图:
插件效果图
我觉得这个效果还是挺高频且实用的,奈何weui里面没有这个扩展,只能自己在网上搜索并改进了。为了方便使用,我已经把左右滑动效果封装成了一个jquery插件了,读者也可以根据需要修改其代码做更多的扩展。
1、列表项html
先贴一下列表项的html代码:
<a href="#" class="weui-media-box weui-media-box_appmsg swipte_item">
<div class="weui-media-box__hd">
<img class="weui-media-box__thumb" src="thumbnail.png">
</div>
<div class="weui-media-box__bd">
<h4 class="weui-media-box__title"></h4>
<p class="weui-media-box__desc"></p>
</div>
<li class="weui-swiped-btn weui-swiped-btn_warn swipe_btn">拒接</li>
<li class="weui-swiped-btn accept_btn">接单</li>
</a>
其中,两个li标签的class属性可以自定义,后续生成滑动实例要用到,还有,我用的是weui,写出来是如上的效果,读者最好根据需求自行制作控件。
2、列表项css
随后是css代码:
.weui-swiped-btn.weui-swiped-btn_warn.swipe_btn {
color: white;
position: absolute;
right: -67px;
width: 35px;
text-align: center;
height: 70px;
line-height: 70px;
}
.weui-swiped-btn.accept_btn {
color: white;
background: #1AAD19;
position: absolute;
left: -67px;
width: 35px;
text-align: center;
height: 70px;
line-height: 70px;
}
读者根据自己的需求修改就好了,这里面有个问题,就是left、right的偏移和width不一样,我暂时没找出问题根源,只能在插件里通过增加滑动偏移来抵消掉负偏移,不知道哪位大神能指导一下。
3、滑动插件js代码
借鉴前人代码基础上,已经封装成了JQuery代码,能实现左右双向的滑动:
/* *
* @brief 列表项左滑右滑功能创建
* 使用方法:$('.itemWipe').touchWipe({itemBtn: '.item-button'});
* @param itemWipe 条目样式名
* itemBtn 滑动后出现的按钮样式名(左右按钮大小应一致,传入任一个即可)
* @return 带滑动效果的列表项
* */
(function ($) {
$.fn.touchWipe = function (option) {
var defaults = {
itemBtn: '.item-delete', //删除元素
};
var opts = $.extend({}, defaults, option); //配置选项
var btnWidth = $(opts.itemBtn).width() + 32; //此处有文章中说的问题,望指导
var initX; //触摸位置X
var initY; //触摸位置Y
var moveX; //滑动时的位置X
var moveY; //滑动时的位置Y
var X = 0; //移动距离X
var Y = 0; //移动距离Y
var flagX = 0; //是否是左右滑动 0为初始,1为左右,2为上下,在move中设置,在end中归零
var objX = 0; //目标对象位置
$(this).on('touchstart', function (event) {
//console.log('start..');
var obj = this;
initX = event.targetTouches[0].pageX;
initY = event.targetTouches[0].pageY;
//console.log(initX + ':' + initY);
objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
//console.log(objX);
if (objX == 0) {
$(this).on('touchmove', function (event) {
// 判断滑动方向,X轴阻止默认事件,Y轴跳出使用浏览器默认
if (flagX == 0) {
setScrollX(event);
return;
} else if (flagX == 1) {
event.preventDefault();
} else {
return;
}
var obj = this;
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X >= 0) {
var l = Math.abs(X);
obj.style.WebkitTransform = "translateX(" + l + "px)";
if (l > btnWidth) {
l = btnWidth;
obj.style.WebkitTransform = "translateX(" + l + "px)";
}
} else if (X < 0) {
var l = Math.abs(X);
obj.style.WebkitTransform = "translateX(" + -l + "px)";
if (l > btnWidth) {
l = btnWidth;
obj.style.WebkitTransform = "translateX(" + -l + "px)";
}
}
});
} else if (objX < 0) {
$(this).on('touchmove', function (event) {
// 判断滑动方向,X轴阻止默认事件,Y轴跳出使用浏览器默认
if (flagX == 0) {
setScrollX(event);
return;
} else if (flagX == 1) {
event.preventDefault();
} else {
return;
}
var obj = this;
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X >= 0) {
var r = -btnWidth + Math.abs(X);
obj.style.WebkitTransform = "translateX(" + r + "px)";
if (r > 0) {
r = 0;
obj.style.WebkitTransform = "translateX(" + r + "px)";
}
} else { //向左滑动
obj.style.WebkitTransform = "translateX(" + -btnWidth + "px)";
}
});
} else {
$(this).on('touchmove', function (event) {
// 判断滑动方向,X轴阻止默认事件,Y轴跳出使用浏览器默认
if (flagX == 0) {
setScrollX(event);
return;
} else if (flagX == 1) {
event.preventDefault();
} else {
return;
}
var obj = this;
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X <= 0) {
var r = btnWidth + Math.abs(X);
obj.style.WebkitTransform = "translateX(" + r + "px)";
if (r > 0) {
r = 0;
obj.style.WebkitTransform = "translateX(" + r + "px)";
}
} else { //向右滑动
obj.style.WebkitTransform = "translateX(" + btnWidth + "px)";
}
});
}
})
//结束时判断,并自动滑动到底或返回
$(this).on('touchend', function (event) {
var obj = this;
objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
if (objX > -btnWidth / 2 && objX <= 0) {
obj.style.transition = "all 0.2s";
obj.style.WebkitTransform = "translateX(" + 0 + "px)";
obj.style.transition = "all 0";
objX = 0;
} else if (objX > btnWidth / 2) {
obj.style.transition = "all 0.2s";
obj.style.WebkitTransform = "translateX(" + btnWidth + "px)";
obj.style.transition = "all 0";
} else if (objX < btnWidth / 2 && objX > 0) {
obj.style.transition = "all 0.2s";
obj.style.WebkitTransform = "translateX(" + 0 + "px)";
obj.style.transition = "all 0";
objX = 0;
} else {
obj.style.transition = "all 0.2s";
obj.style.WebkitTransform = "translateX(" + -btnWidth + "px)";
obj.style.transition = "all 0";
objX = -btnWidth;
}
flagX = 0;
})
//设置滑动方向
function setScrollX(event) {
moveX = event.targetTouches[0].pageX;
moveY = event.targetTouches[0].pageY;
X = moveX - initX;
Y = moveY - initY;
if (Math.abs(X) > Math.abs(Y)) {
flagX = 1;
} else {
flagX = 2;
}
return flagX;
}
//链式返回
return this;
};
})(jQuery);
接下来,我会其中关键的地方和思路解释清楚,具体内容就需要读者自己理解了:
1、获得首次点击时的像素点(x,y)坐标值,并通过WebkitTransform获得当前列表项偏移的像素(objX等于0说明没有偏移,大于0说明向右偏移了,小于0说明向左偏移了)。
2、touchmove事件触发后,获得当前的手指点住的像素点(x,y)坐标,通过与初始坐标相减,获得手指滑动的方向(变量X大于0是右滑,小于0是左滑)。
3、随后,判断当前x轴的偏移量,当超过按钮一半是自动滑动到底,小于一半是返回。
4、最后,在你的js代码中,通过$('.itemWipe').touchWipe({itemBtn: '.item-button'});
即可为指定html标签绑定此功能。
以上。
github传送地址:https://github.com/JunJieDing666/YouZhiGou
若有错误烦请指出,有地方不理解欢迎讨论。
网友评论