功能比较简单常见,最近整理一下做备份记录。先看看线上 整体实际效果 ,基于原生js,不依赖其他类库
博客园地址 https://www.cnblogs.com/surfaces/p/8426056.html
github 地址:https://taylor-swift-1989.github.io/h5/swipeDelete/swipeDelete.html
下面是swipeDelete 用法 demo
默认参数
var defaults = {
distance:80, //滑动距离
units:'px', //默认单位
touchStart:function(){},//触摸开始回调
opened:function(){},//展开后回调
closed:function(){},//关闭后回调
duration:100,//毫秒
deleteBtn:'.swipe-delete-btn', //删除元素
direction:'left', //滑动方向
deleteClose:true, //点击删除是否 关闭
deleteFn:function(){} //删除事件 retuan false 不关闭 // retuan true 关闭
};
dom 节点如下 支持种结构
A li 元素运动 transform: translateX(2px); 滑动元素和删除元素 父子 节点关系
<li id="li" class="swipe-delete-element list-li" > //该节点 位移 transform: translateX
<div class="con ">
00 向左侧 滑动删除 一起过来
</div>
<div class="swipe-delete-btn btn">删除0</div>
</li>
B con 元素运动 transform: translateX(2px); 滑动元素和删除元素 兄弟节点关系
<li id="li" class=" list-li" >
<div class="con swipe-delete-element "> //该节点 位移 transform: translateX
11 向左侧 滑动删除 藏在后面
</div>
<div class="swipe-delete-btn btn" style="right:0px;">删除1</div>
</li>
对应的js 如下,有疑问可以看下面源代码 附录
参数 deleteClose:false,用法 点击 删除按钮并收回 滑动元素, 点击事件回调函数 deleteFn里面 return true 可以收回,或者通过 sa5.swipeClose() 方法促其关闭;
var swipedeletecontent5=document.querySelectorAll(".swipe-delete-element")[5];
var sa5=new swipeDelete(swipedeletecontent5,{
distance:160,
deleteBtn:'.swipe-delete-btn2',
deleteClose:false,
//direction:'left',
touchStart:function(e){
console.log("sa6 touchStart"+this.innerHTML);
//console.log(this.innerHTML==e.target.innerHTML);
},
opened:function(e){
//console.log("sa6 opened");
console.log("sa6 opened"+this.innerHTML);
},
closed:function(e){
//console.log("sa6 closed");
console.log("sa6 closed"+this.innerHTML);
},
deleteFn:function(e){
var that=this;
console.log(e.target.parentNode);
if(that.className=="on1"){
alert("5on11"+that.innerHTML+'不 可以关闭'); }else if(that.className=="on2"){
alert("5on22"+that.innerHTML+'可以关闭');
return true; //关闭
}
}
})
sa5.swipeOpen();
//console.log(sa5) document.getElementById("j_opend").addEventListener("click",function(){
var swipe5=document.querySelector(".swipe5").querySelector(".swipe-delete-element");
var flagOpen=swipe5.getAttribute("data-lock"); if(flagOpen=='false'){
sa5.swipeOpen();
this.innerHTML="swipe5 关闭"
} if(swipe5.getAttribute("data-lock")=='true'){
sa5.swipeClose(); this.innerHTML="swipe5打开 "
} })
swipeDelete静态方法 API , 关闭与打开
var sa5=new swipeDelete(swipedeletecontent5,{}); sa5.swipeOpen(); sa5.swipeClose();
创建的swipeDelete 对象 ,可省略new 关键字,swipeDelete 类 内部 如下
附上完整代码
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>滑动删除</title>
<meta http-equiv="X-UA-Compatible" content="edge,chrome=1" />
<meta http-equiv="Cache-Control" content="no-siteapp" /> <!-- 避免转码 -->
<meta name="keywords" content=""/>
<meta name="description" content=""/>
<meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width" />
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta name="apple-itunes-app" content="app-id=932758491"> <meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0"> <meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="address=no">
<meta name="format-detection" content="email=no" >
<meta name="apple-mobile-web-app-title" content="">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="screen-orientation" content="portrait"> <!-- uc强制竖屏 设置横屏应用得在config里面设置,网页是无法做到的 -->
<meta name="x5-orientation" content="portrait"> <!-- QQ强制竖屏 -->
<meta name="msapplication-tap-highlight" content="no"> <!-- windows phone 点击无高光 -->
<meta name="HandheldFriendly" content="true"> <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <style>
/* CSS Document */
@charset "utf-8";
html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,span,img,button ,em,i,b{margin:0;padding:0;}
html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent;min-width:320px;font-size:62.5%;}
body{font-family:"微软雅黑",'Helvetica Neue',Helvetica,tahoma,arial,sans-serif;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;line-height:1;font-size:14px;-webkit-touch-callout:none;-webkit-user-select:none;}
article,aside,dialog,figure,footer,header,hgroup,menu,nav,section{display:block}
dl,li,menu,ol,ul{list-style:none}
address,em,i,th{font-weight:400;font-style:normal}
a{color:#999;display:block;}
a:link,a:visited{color:#999;text-decoration:none;cursor:pointer}
a:hover{cursor:pointer}
a:active,a:focus{outline:0;}
img{width:100%;border:0;vertical-align:middle;-webkit-user-select:none;}
input,select{outline:0}
h1,h2,h3,h4,h5,h6{font-size:100%;font-variant:normal;font-weight:normal;}
button,input[type=button],input[type=tel],input[type=reset],input[type=submit]{line-height:normal!important;-webkit-appearance:none}
::-webkit-input-placeholder{color:#777;}
::input-placeholder{color:#777;}
input:focus::-webkit-input-placeholder{-webkit-transition:.1s;opacity:0;}
input:focus::input-placeholder{transition:.1s;opacity:0;}
header {
background: #f7483b;
border-bottom: 1px solid #ccc
} header h2 {
text-align: center;
line-height: 54px;
font-size: 16px;
color: #fff
} .list-ul { touch-action: none;
overflow: hidden
} .list-li {
line-height: 60px; height: 60px;
border-bottom: 1px solid #fcfcfc;
position: relative; color: #666;
background: #999;
-webkit-transition-duration:-webkit-transform .1s;
transition-duration:transform .1s; -webkit-transition-timing-function:ease-out ;transition-timing-function:ease-out ;
}
.con{ padding: 0 15px; position: relative; z-index: 7; background: #f2f2f2;}
.btn {
position: absolute;
top: 0;
right: -80px;
text-align: center;
background: #ffcb20;
color: #fff;
width: 80px; z-index: 2;
} .btn div {
float: left; display: inline-block; height: 60px;;
background: #ffcb20;
color: #fff;
width: 80px; z-index: 2;
}
.btn div:nth-of-type(2) {
background: red; }
</style> </head> <body>
<header>
<h2>suface 滑动删除 列表</h2>
</header>
<div style="height: 50px;; text-align: center; line-height: 50px;">suface 滑动删除 例子</div> <section class="list">
<ul class="list-ul">
<li id="li" class="swipe-delete-element list-li" > <!-- //该节点 位移 transform: translateX-->
<div class="con ">
00 向左侧 滑动删除 一起过来
</div>
<div class="swipe-delete-btn btn">删除0</div>
</li> <li id="li" class=" list-li" >
<div class="con swipe-delete-element "> <!-- //该节点 位移 transform: translateX-->
11 向左侧 滑动删除 藏在后面
</div>
<div class="swipe-delete-btn btn" style="right:0px;">删除1</div>
</li> <li id="li" class=" list-li swipe-delete-element" >
<div class="con ">
22 向 you 侧 滑动删除
</div>
<div class="swipe-delete-btn btn" style="right:auto; left: -80px;">删除2</div>
</li> <li id="li" class=" list-li " >
<div class="con swipe-delete-element">
33 向you 侧 滑动删除 藏在后面
</div>
<div class="swipe-delete-btn btn" style="right:auto; left: 0px;">删除3</div>
</li> <li id="li" class=" list-li swipe-delete-element" >
<div class="con ">
44 向左侧 滑动删除 多个 点击
</div>
<div class="swipe-delete-btn btn " style="right: -160px;width:160px">
<div style="width: 80px;" class="on1">4删除111 多个</div>
<div style="width: 80px;" class="on2">4删除222 多个</div>
</div>
</li> <li id="li" class=" list-li swipe5" >
<div class="con swipe-delete-element " >
55 向左侧 滑动删除 藏在后面 swipe5
</div>
<div class="swipe-delete-btn2 btn" style="right: 0px;width:160px">
<div style="width: 80px;" class="on1">5删除111 多个</div>
<div style="width: 80px;" class="on2">5删除222 多个</div>
</div>
</li> <li id="li" class=" list-li " >
<div class="con swipe-delete-element66">
666 swipe-delete-element66 参数传入
</div>
<div class="swipe-delete-btn2 btn" style="right: 0px;width:160px">
<div style="width: 80px;" class="on1">6删除111 多个</div>
<div style="width: 80px;" class="on2">6删除222 多个</div>
</div>
</li>
</ul>
</section> <div style="height: 400px;;"> <div id="j_opend" style="padding: 20px; text-align: center; background:#999; margin: 20px auto;">点击swipe5 关闭 </div> </div> <script> ;(function(window, document, undefined) { function swipeDelete(element,options) {
var _self=this;//此时this指向实例对象 _self.swipeElement =element; if (typeof element === 'string') {
_self.swipeElement =document.querySelector(element);
} //取消new 关键字
return (_self instanceof swipeDelete)? _self.init( _self.swipeElement,options):new swipeDelete(_self.swipeElement,options); }
swipeDelete.prototype = {
constructor: swipeDelete,
extend: function() {
for(var i=1; i<arguments.length; i++)
for(var key in arguments[i])
if(arguments[i].hasOwnProperty(key))
arguments[0][key] = arguments[i][key];
return arguments[0];
}, allowMultiple: true,
endEvent : function() {
var el = document.createElement("div");
var transEndEventNames = {
WebkitTransition: "webkitTransitionEnd",
transition: "transitionend"
};
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return transEndEventNames[name]
}
}
el = null;
return false
}(),
init: function(element,options) {
var _self = this;
var options=options||{};
var defaults = {
distance:80, //滑动距离
units:'px', //默认单位
touchStart:function(){},//触摸开始毁掉
opened:function(){},//展开后回调
closed:function(){},//关闭后回调
duration:100,//毫秒
deleteBtn:'.swipe-delete-btn', //删除元素
direction:'left', //滑动方向
deleteClose:true, //点击删除是否 关闭
deleteFn:function(){} //删除事件 retuan false 不关闭 // retuan true 关闭
}; _self.options=_self.extend({},defaults,options);
_self.swipeEvent(element,_self.options); }, swipeEvent:function(element,options){ var _self=this;
var ele=element; var isMoved = false;
var isTouched = true;
var isScrolling = undefined;//目标对象位置
var touchesDiff = 0;////移动距离
var startX=0;
var startPos={
x : 0,
y : 0,
startTime:+new Date
};
var scale=false;
var isGo=false;
var deleteBtn=ele.querySelectorAll(options.deleteBtn)[0]; //删除元素 可能是子元素 也可能同一级别 兄弟节点
var deleteFn=options.deleteFn; //删除元素回调时间
var distance=options.distance;//最大滑动距离
var direction=options.direction;
var deleteClose =options.deleteClose;
var units=options.units;
ele.setAttribute("data-lock","false");
if(!deleteBtn){
deleteBtn=ele.parentNode.nodeType==1&&ele.parentNode.querySelectorAll(options.deleteBtn)[0];
scale=true;
}; _self.direction = direction; deleteBtn.addEventListener('click', function(event) {
var that=this;
var event=event;
var target=event.target; if(options.deleteClose==true){
_self.swipeClose(ele,options);
} if(options.deleteFn&&options.deleteFn.apply(target,arguments)==true){
_self.swipeClose(ele,options);
}
event.stopPropagation();
}); ele.addEventListener('click', function(event) {
_self.swipeClose(ele,options); }); ele.addEventListener('touchstart', function(event) { var touchs = event.touches[0]; //手指头的一个 if (!_self.allowMultiple) { //不允许同时 展示多个删除 // _self.swipeClose(ele,options)
//return false;
}; //不能滑动 有没有 缩进去的 isMoved = false;
isTouched = true;
isScrolling = undefined;
startPos={
x: touchs.pageX||touchs.clientX,
y: touchs.pageY||touchs.clientY,
startTime:+new Date
}; ele.style.webkitTransitionDuration = ele.style.transitionDuration="0s"; startX=(ele.style.WebkitTransform.replace(/translateX\(/g, "").replace(/(px|rem|%)\)/g, "")) * 1||(ele.style.transform.replace(/translateX\(/g, "").replace(/(px|rem|%)\)/g, "")) * 1||0; if(ele.getAttribute("data-lock")=="false"){
options.touchStart&&options.touchStart.apply(ele,arguments);
} document.addEventListener('touchmove', function(event) {
var event=event||window.event;
if (!isTouched){
return;
} if ( event.touches.length > 1 || event.scale && event.scale !== 1){
return;
} var touchs = event.changedTouches[0];
var movPos={
x : touchs.pageX||touchs.clientX,
y : touchs.pageY||touchs.clientY
}; if (typeof isScrolling === 'undefined') {
isScrolling = !!( isScrolling || Math.abs(movPos.x-startPos.x) < Math.abs(movPos.y-startPos.y) );
} if (isScrolling) {
isTouched = false;
return;
} //event.preventDefault();
//if (!event.defaultPrevented) {
event.preventDefault();
// } _self.touchesDiff=movPos.x-startPos.x+ startX; //滑动的距离
isMoved = true; if(direction=='left'){ //向左滑 if(_self.touchesDiff>=0){
var l =isGo? Math.abs(_self.touchesDiff)*0.1:0;
ele.style.WebkitTransform=ele.style.transform = "translateX(" + l +units+") translateZ(0)"; }else{ var l = Math.abs(_self.touchesDiff);
isGo=true;
ele.style.WebkitTransform=ele.style.transform = "translateX(" + -l +units+") translateZ(0)";
if (l > distance) {
if(scale){
l = (distance+(l-distance)*0.39);;
}else{
l=distance;
}
ele.style.WebkitTransform=ele.style.transform = "translateX(" + -l +units+") translateZ(0)";
} } } if(direction=='right'){ //向右侧 if(_self.touchesDiff>=0){ var l = Math.abs(_self.touchesDiff);
isGo=true;
ele.style.WebkitTransform=ele.style.transform = "translateX(" + l +units+") translateZ(0)";
if (l > distance) {
if(scale){
l = (distance+(l-distance)*0.39);; }else{
l=distance;
} ele.style.WebkitTransform=ele.style.transform = "translateX(" + l +units+" ) translateZ(0)";
}
}else{
var l =isGo? Math.abs(_self.touchesDiff)*0.1:0;
ele.style.WebkitTransform=ele.style.transform = "translateX(-" + l +units+") translateZ(0)";
} } }); document.addEventListener('touchend', function(event) {
if (!isTouched|| !isMoved) {
isMoved = false;
isTouched = false;
return;
}
isMoved = false;
isTouched = false;
isGo=false;
var touchs = event.changedTouches[0]; //手指头的一个
var endPos={
x : touchs.pageX||touchs.clientX,
y : touchs.pageY||touchs.clientY,
endTime:+new Date
};
var timeDiff=endPos.endTime-startPos.startTime;
var distance=options.distance;
var direction=options.direction;
var touchesDiff=_self.touchesDiff;
var action="close"; //是否关闭状态
if(ele.getAttribute("data-lock")=='true'){
action = 'open';
} if (timeDiff < 300 && (touchesDiff < -10 && direction === 'left' || touchesDiff > 10 && direction === 'right')
|| timeDiff > 300 && (touchesDiff < -parseInt(distance/3) &&direction === 'left' || touchesDiff > parseInt(distance/3) && direction === 'right')
)
{
if(action == 'close'){ _self.swipeOpen(ele,options) }else{
_self.swipeClose(ele,options);
isGo=false;
event.preventDefault();
}
}else{ _self.swipeClose(ele,options);
isGo=false;
event.preventDefault(); } }); });
return this; }, swipeClose:function(ele,options){
var _self=this;
var ele= ele||_self.swipeElement;
var options=options||_self.options;
var fired=false;
var endEvent=_self.endEvent;
var units=options.units;
var duration=Number(options.duration/1000)||100;
var sa=0;
var handler = function(e) {
ele.removeEventListener(endEvent, arguments.callee, false);
fired = true;
handler=null;
sa++; if(sa>1){return }
ele.setAttribute("data-lock","false");
options.closed&&options.closed.apply(ele,arguments);;
callback=null; }; ele.style.WebkitTransform=ele.style.transform = "translateX(-" + 0 + units+") ";
ele.style.webkitTransitionDuration = ele.style.transitionDuration=duration+"s";
ele.addEventListener(endEvent,handler.bind(this), false); setTimeout(function() {
if (fired) {
return
}
handler();
}, parseInt(duration+25)); return this;
},
swipeOpen:function(ele,options){
var _self=this;
var ele= ele||_self.swipeElement;
var options=options||_self.options;
var distance=options.distance;//最大滑动距离
var units=options.units;
var duration=Number(options.duration/1000)||100;
var sa=0;
var fired=false;
var endEvent=_self.endEvent;
var handler = function (e) {
ele.removeEventListener(endEvent, arguments.callee, false);
fired=true;
handler=null; sa++; if(sa>1){return }
ele.setAttribute("data-lock","true");
if(ele.getAttribute("data-lock")=="true"){
options.opened&&options.opened.apply(ele,arguments);
}
}; if(options.direction=="left"){
distance=distance*-1;
} ele.clientLeft;
ele.style.WebkitTransform=ele.style.transform = "translateX(" + distance + units+") ";
ele.style.webkitTransitionDuration = ele.style.transitionDuration=duration+"s";
ele.addEventListener(endEvent,handler.bind(this), false); setTimeout(function() {
if (fired) {
return
}
handler();
}, parseInt(duration+25)); return this;
}
}; if (typeof exports == 'object') {
module.exports = swipeDelete;
}
else if (typeof define == 'function' && define.amd) {
define(function() {
return swipeDelete;
});
}
else {
window.swipeDelete = swipeDelete;
} })(window,document); var swipedeletecontent=document.querySelectorAll(".swipe-delete-element")[0];
var sa= swipeDelete(swipedeletecontent,{
direction:'left',
deleteFn:function(e){
alert(this.innerHTML)
console.log(e.target);
}
}) var swipedeletecontent1=document.querySelectorAll(".swipe-delete-element")[1];
var sa1= swipeDelete(swipedeletecontent1,{ deleteFn:function(e){
alert(this.innerHTML);
console.log(e.target); }
}) var swipedeletecontent2=document.querySelectorAll(".swipe-delete-element")[2];
var sa2= swipeDelete(swipedeletecontent2,{
direction:'right',
deleteFn:function(e){
alert(this.innerHTML);
console.log(e.target); }
})
//console.log(sa2.swipeOpen()) var swipedeletecontent3=document.querySelectorAll(".swipe-delete-element")[3];
var sa3= swipeDelete(swipedeletecontent3,{
direction:'right',
deleteFn:function(e){
alert(this.innerHTML);
console.log(e.target); }
})
//console.log(sa3); var swipedeletecontent4=document.querySelectorAll(".swipe-delete-element")[4];
var sa4= swipeDelete(swipedeletecontent4,{
distance:160,
direction:'left',
deleteFn:function(e){
//console.log(e.target); var that=this; if(that.className=="on1"){
alert("on1"+that.innerHTML)
}else if(that.className=="on2"){
alert("on2"+that.innerHTML)
}
}
})
//console.log(sa4.swipeOpen()) var swipedeletecontent5=document.querySelectorAll(".swipe-delete-element")[5];
var sa5=new swipeDelete(swipedeletecontent5,{
distance:160,
deleteBtn:'.swipe-delete-btn2',
deleteClose:false,
//direction:'left',
touchStart:function(e){
console.log("sa6 touchStart"+this.innerHTML);
//console.log(this.innerHTML==e.target.innerHTML);
},
opened:function(e){
//console.log("sa6 opened");
console.log("sa6 opened"+this.innerHTML);
},
closed:function(e){
//console.log("sa6 closed");
console.log("sa6 closed"+this.innerHTML);
},
deleteFn:function(e){
var that=this;
console.log(e.target.parentNode);
if(that.className=="on1"){
alert("5on11"+that.innerHTML+'不 可以关闭'); }else if(that.className=="on2"){
alert("5on22"+that.innerHTML+'可以关闭');
return true; //关闭
}
}
})
sa5.swipeOpen();
//console.log(sa5) document.getElementById("j_opend").addEventListener("click",function(){
var swipe5=document.querySelector(".swipe5").querySelector(".swipe-delete-element");
var flagOpen=swipe5.getAttribute("data-lock"); if(flagOpen=='false'){
sa5.swipeOpen();
this.innerHTML="swipe5 关闭"
} if(swipe5.getAttribute("data-lock")=='true'){
sa5.swipeClose(); this.innerHTML="swipe5打开 "
} }) var sa66=new swipeDelete(".swipe-delete-element66",{
distance:160,
deleteBtn:'.swipe-delete-btn2',
deleteClose:true,
//direction:'left',
touchStart:function(e){
console.log("sa6 touchStart"+this.innerHTML);
//console.log(this.innerHTML==e.target.innerHTML);
},
opened:function(e){
//console.log("sa6 opened");
console.log("sa6 opened"+this.innerHTML);
},
closed:function(e){
//console.log("sa6 closed");
console.log("sa6 closed"+this.innerHTML);
},
deleteFn:function(e){
var that=this;
console.log(e.target.parentNode);
if(that.className=="on1"){
alert("6on11"+that.innerHTML); }else if(that.className=="on2"){
alert("6on22"+that.innerHTML) }
//console.log(this.innerHTML); }
})
console.log(sa66);
</script> </body>
</html>