lemon_sideslip_list
功能描述
实用vue.js扩展的滑动删除插件,是基于vue.js 框架实现手势滑动删除功能
依赖的模块
vue
快速使用
<script type="text/javascript">
(function(doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function() {
var clientWidth = docEl.clientWidth;
if(!clientWidth) return;
docEl.style.fontSize = 20 * (clientWidth / 375) + 'px';
};
if(!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
<style>
html,body { margin:0px;}
.app-message-box { width:100%; height:auto; float:left; overflow: hidden}
.app-message-box ul { width:100%; height:auto; float:left;overflow: hidden; list-style:none; padding:0px 5%; margin-bottom:70px;}
.app-message-box ul li { width:100%; height:50px; float:left; border-bottom:1px solid #EFEFEF;}
.app-message-box ul li a {width:100%; height:50px; float:left; line-height: 50px; font-size:16px;}
/* 左侧滑块删除 */
.vue-list-del-data { -webkit-transition: all 0.2s;transition: 0.2s;position: relative;user-select: none;}
.vue-list-del-data[ data-type="0"] { transform: translateX(0px);}
.vue-list-del-data[ data-type="1"] { transform: translateX(-60px);}
.vue-list-del-data div.content { background: #fff;-webkit-box-sizing: border-box;box-sizing: border-box; justify-content: flex-end;position: absolute;left: 0;right: 0;top: 0;bottom: 0;}
.vue-list-del-data div.delete { width:100px;height: 50px;background: #DD4338; font-size: 15px;color: #fff;text-align: center;line-height:50px;position: absolute;top: 0;right: -90px;}
</style>
<div class="app-message-box">
<ul id="message_list" style="margin:0px;">
<li v-cloak class="vue-list-del-data" v-for="(vo,index) in list" data-type="0">
<div class="content" @touchstart.capture="touchStart" @touchend.capture="touchEnd" @touchmove.capture="touchMove" @click="skip(index)">
<a>{{vo.title}}</a>
</div>
<div class="delete" @click="deleteItem" :data-index="index">删除</div>
</li>
</ul>
</div>
<script type="text/javascript" src="./libs/vue.js"></script>
<script type="text/javascript">
var message_list = new Vue({
el: '#message_list',
data: {
list: [{id:1,title:'测试1'},{id:2,title:'测试2'},{id:3,title:'测试3'},{id:4,title:'测试4'}],
startX:0,
startY:0,
endX:0,
endY:0,
moveX:0,
disX:0
},
methods:vue_methods_list_del('.vue-list-del-data',function(el,index){
alert('删除');
},function(el,index){
alert('点击');
})
});
function vue_methods_list_del(dom_str,click_callback,del_callback){
return {
skip:function(index) {
if(this.checkSlide()) {
this.restSlide();
} else {
//alert('----'+this.list[index].user_name);
click_callback(this,index);
}
},
//滑动开始
touchStart:function(e) {
// 记录初始位置
this.startX = e.touches[0].clientX;
this.startY = e.touches[0].clientY;
},
//滑块中
touchMove:function(e){
var e = e || event;
var wd= 58;
var parentElement = e.currentTarget.parentElement;
var moveEndX = e.touches[0].clientX;
var moveEndY = e.touches[0].clientY;
var X = moveEndX - this.startX;
var Y = moveEndY - this.startY;
if(e.touches.length == 1) {
this.moveX = e.touches[0].clientX
this.disX = this.startX - this.moveX;
//$lemon.toast('X:'+X +'||'+ 'Y:'+Y);
if(this.disX < 0 || this.disX == 0) {
parentElement.style.transform = "translateX(0px)";
// 大于0,表示左滑了,此时滑块开始滑动
}else if ( X < -90 && Y<90 && this.disX > 0) {
//具体滑动距离我取的是 手指偏移距离*5。
parentElement.style.transform = "translateX(-" + this.disX*5 + "px)";
// 最大也只能等于删除按钮宽度
if (this.disX*5 >=wd) {
this.restSlide();
parentElement.style.transform = "translateX(-" +wd+ "px)";
parentElement.dataset.type = 1;
}
}else{
parentElement.style.transform = "translateX(0px)";
}
}
},
//滑动结束
touchEnd:function(e) {
// 当前滑动的父级元素
var parentElement = e.currentTarget.parentElement;
// 记录结束位置
this.endX = e.changedTouches[0].clientX;
//$lemon.toast(parentElement.dataset.type);
var e = e || event;
var wd= 98;
if (e.changedTouches.length == 1 && parentElement.dataset.type==1) {
var endX = e.changedTouches[0].clientX;
this.disX = this.startX - endX;
if ((this.disX*5) < (wd/2)) {
this.restSlide();
parentElement.style.transform = "translateX(0px)";
parentElement.dataset.type = 0;
}else{
//大于一半 滑动到最大值
this.restSlide();
parentElement.style.transform = "translateX(-" +wd+ "px)";
parentElement.dataset.type = 1;
}
}
this.startX = 0;
this.startY = 0;
this.endX = 0;
this.endY = 0;
},
//判断当前是否有滑块处于滑动状态
checkSlide:function() {
var listItems = document.querySelectorAll(dom_str);
for(var i = 0; i < listItems.length; i++) {
if(listItems[i].dataset.type == 1) {
return true;
}
}
return false;
},
//复位滑动状态
restSlide:function() {
var listItems = document.querySelectorAll(dom_str);
// 复位
for(var i = 0; i < listItems.length; i++) {
listItems[i].dataset.type = 0;
listItems[i].style.transform = "translateX(0px)";
}
},
//删除
deleteItem:function(e) {
// 当前索引
var index = e.currentTarget.dataset.index;
del_callback(this,index);
// 复位
this.restSlide();
// 删除
this.list.splice(index, 1);
}
};
};
</script>
特别说明
使用本模块注意会与同vue.js模块冲突,请开发者谨慎选择,本模块为1.0版本,后续会陆续更新。``