js仿QQ中對(duì)聯(lián)系人向左滑動(dòng)、滑出刪除按鈕的操作
本文實(shí)例為大家分享實(shí)現(xiàn)類(lèi)似QQ中對(duì)聯(lián)系人的操作:向左滑動(dòng),滑出刪除按鈕。滑動(dòng)超過(guò)一半時(shí)松開(kāi)則自動(dòng)滑到底,不到一半時(shí)松開(kāi)則返回原處。

純js實(shí)現(xiàn)
使用了h5的touchmove等事件,以及用js動(dòng)態(tài)改變css3的translate屬性來(lái)達(dá)到動(dòng)畫(huà)效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=1">
<title>html5向左滑動(dòng)刪除特效</title>
<style>
* {
padding: 0;
margin: 0;
list-style: none;
}
header {
background: #f7483b;
border-bottom: 1px solid #ccc
}
header h2 {
text-align: center;
line-height: 54px;
font-size: 16px;
color: #fff
}
.list-ul {
overflow: hidden
}
.list-li {
line-height: 60px;
border-bottom: 1px solid #fcfcfc;
position: relative;
padding: 0 12px;
color: #666;
background: #f2f2f2;
-webkit-transform: translateX(0px);
}
.btn {
position: absolute;
top: 0;
right: -80px;
text-align: center;
background: #ffcb20;
color: #fff;
width: 80px
}
</style>
<script>
/*
* 描述:html5蘋(píng)果手機(jī)向左滑動(dòng)刪除特效
*/
window.addEventListener('load', function() {
var initX; //觸摸位置
var moveX; //滑動(dòng)時(shí)的位置
var X = 0; //移動(dòng)距離
var objX = 0; //目標(biāo)對(duì)象位置
window.addEventListener('touchstart', function(event) {
event.preventDefault();
var obj = event.target.parentNode;
if (obj.className == "list-li") {
initX = event.targetTouches[0].pageX;
objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
}
if (objX == 0) {
window.addEventListener('touchmove', function(event) {
event.preventDefault();
var obj = event.target.parentNode;
if (obj.className == "list-li") {
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X >= 0) {
obj.style.WebkitTransform = "translateX(" + 0 + "px)";
} else if (X < 0) {
var l = Math.abs(X);
obj.style.WebkitTransform = "translateX(" + -l + "px)";
if (l > 80) {
l = 80;
obj.style.WebkitTransform = "translateX(" + -l + "px)";
}
}
}
});
} else if (objX < 0) {
window.addEventListener('touchmove', function(event) {
event.preventDefault();
var obj = event.target.parentNode;
if (obj.className == "list-li") {
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X >= 0) {
var r = -80 + Math.abs(X);
obj.style.WebkitTransform = "translateX(" + r + "px)";
if (r > 0) {
r = 0;
obj.style.WebkitTransform = "translateX(" + r + "px)";
}
} else { //向左滑動(dòng)
obj.style.WebkitTransform = "translateX(" + -80 + "px)";
}
}
});
}
})
window.addEventListener('touchend', function(event) {
event.preventDefault();
var obj = event.target.parentNode;
if (obj.className == "list-li") {
objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
if (objX > -40) {
obj.style.WebkitTransform = "translateX(" + 0 + "px)";
objX = 0;
} else {
obj.style.WebkitTransform = "translateX(" + -80 + "px)";
objX = -80;
}
}
})
})
</script>
</head>
<body>
<header>
<h2>消息列表</h2>
</header>
<section class="list">
<ul class="list-ul">
<li id="li" class="list-li">
<div class="con">
你的快遞到了,請(qǐng)到樓下簽收
</div>
<div class="btn">刪除</div>
</li>
<li class="list-li">
<div class="con">
哇,你在干嘛,快點(diǎn)來(lái)啊就等你了
</div>
<div class="btn">刪除</div>
</li>
</ul>
</section>
</body>
</html>
做成zepto插件
實(shí)際項(xiàng)目中,我們可能有很多個(gè)地方會(huì)用到這個(gè)功能?,F(xiàn)在我們將這個(gè)功能做成zepto插件,方便后面使用。
這個(gè)插件,我們僅實(shí)現(xiàn)這個(gè)功能,然后傳入?yún)?shù)(刪除按鈕的樣式名),讓程序在js中計(jì)算所需要滑動(dòng)的距離,方便復(fù)用。
zepto.touchWipe.js
/**
* zepto插件:向左滑動(dòng)刪除動(dòng)效
* 使用方法:$('.itemWipe').touchWipe({itemDelete: '.item-delete'});
* 參數(shù):itemDelete 刪除按鈕的樣式名
*/
;
(function($) {
$.fn.touchWipe = function(option) {
var defaults = {
itemDelete: '.item-delete', //刪除元素
};
var opts = $.extend({}, defaults, option); //配置選項(xiàng)
var delWidth = $(opts.itemDelete).width();
var initX; //觸摸位置
var moveX; //滑動(dòng)時(shí)的位置
var X = 0; //移動(dòng)距離
var objX = 0; //目標(biāo)對(duì)象位置
$(this).on('touchstart', function(event) {
event.preventDefault();
var obj = this;
initX = event.targetTouches[0].pageX;
objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
if (objX == 0) {
$(this).on('touchmove', function(event) {
event.preventDefault();
var obj = this;
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X >= 0) {
obj.style.WebkitTransform = "translateX(" + 0 + "px)";
} else if (X < 0) {
var l = Math.abs(X);
obj.style.WebkitTransform = "translateX(" + -l + "px)";
if (l > delWidth) {
l = delWidth;
obj.style.WebkitTransform = "translateX(" + -l + "px)";
}
}
});
} else if (objX < 0) {
$(this).on('touchmove', function(event) {
event.preventDefault();
var obj = this;
moveX = event.targetTouches[0].pageX;
X = moveX - initX;
if (X >= 0) {
var r = -delWidth + Math.abs(X);
obj.style.WebkitTransform = "translateX(" + r + "px)";
if (r > 0) {
r = 0;
obj.style.WebkitTransform = "translateX(" + r + "px)";
}
} else { //向左滑動(dòng)
obj.style.WebkitTransform = "translateX(" + -delWidth + "px)";
}
});
}
})
$(this).on('touchend', function(event) {
event.preventDefault();
var obj = this;
objX = (obj.style.WebkitTransform.replace(/translateX\(/g, "").replace(/px\)/g, "")) * 1;
if (objX > -delWidth / 2) {
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(" + -delWidth + "px)";
obj.style.transition = "all 0";
objX = -delWidth;
}
})
//鏈?zhǔn)椒祷?
return this;
};
})(Zepto);
touchWipe.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" id="viewport" content="width=device-width, initial-scale=1">
<title>html5向左滑動(dòng)刪除特效</title>
<style>
*{ padding:0; margin:0; list-style: none;}
header{ background: #f7483b; border-bottom: 1px solid #ccc}
header h2{ text-align: center; line-height: 54px; font-size: 16px; color: #fff}
.list-ul{ overflow: hidden}
.list-li{ line-height: 60px; border-bottom: 1px solid #fcfcfc; position:relative;padding: 0 12px; color: #666;
background: #f2f2f2;
-webkit-transform: translateX(0px);
}
.btn{ position: absolute; top: 0; right: -80px; text-align: center; background: #ffcb20; color: #fff; width: 80px}
</style>
</head>
<body>
<header>
<h2>消息列表</h2>
</header>
<section class="list">
<ul class="list-ul">
<li id="li" class="list-li">
<div class="con">
你的快遞到了,請(qǐng)到樓下簽收
</div>
<div class="btn">刪除</div>
</li>
<li class="list-li">
<div class="con">
哇,你在干嘛,快點(diǎn)來(lái)啊就等你了
</div>
<div class="btn">刪除</div>
</li>
</ul>
</section>
<p>X: <span id="X"></span></p>
<p>objX: <span id="objX"></span></p>
<p>initX: <span id="initX"></span></p>
<p>moveX: <span id="moveX"></span></p>
<script type="text/javascript" src="http://apps.bdimg.com/libs/zepto/1.1.4/zepto.min.js"></script>
<script type="text/javascript" src="zepto.touchWipe.js"></script>
<script type="text/javascript">
$(function() {
$('.list-li').touchWipe({itemDelete: '.btn'});
});
</script>
</body>
</html>
效果:

實(shí)際項(xiàng)目中的應(yīng)用效果:

消除BUG
到上面一步,基本實(shí)現(xiàn)了我們所需要的功能。但是有幾個(gè)問(wèn)題:
1. 右邊的刪除按鈕點(diǎn)擊失靈,因?yàn)閟pan無(wú)法冒泡到大按鈕上;
2. 非常嚴(yán)重的問(wèn)題,我們給div添加了touchmove事件同時(shí)用preventDefault()屏蔽了原始的瀏覽器事件,導(dǎo)致上下滑動(dòng)div的時(shí)候 頁(yè)面無(wú)法滾動(dòng)了!
第一個(gè)問(wèn)題比較容易解決,我們把span直接去掉,將“刪除”寫(xiě)到css中的:before里,像這樣:
.itemWipe .item-delete:before {
content: '刪除';
color: #fff;
}
對(duì)于第二個(gè)問(wèn)題,網(wǎng)上說(shuō)用iscroll來(lái)解決。我們這里參考手機(jī)QQ中對(duì)聯(lián)系人的滑動(dòng)操作。
大致原理:在滑動(dòng)最開(kāi)始的時(shí)候,判斷是Y軸的移動(dòng)多 還是 X軸的移動(dòng)多。 如果是X軸移動(dòng)大,則判斷為滑動(dòng)刪除操作,我們?cè)偈褂胮reventDefault();
更多關(guān)于滑動(dòng)效果的專(zhuān)題,請(qǐng)點(diǎn)擊下方鏈接查看:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
JavaScript使用setInterval()函數(shù)實(shí)現(xiàn)簡(jiǎn)單輪詢(xún)操作的方法
這篇文章主要介紹了JavaScript使用setInterval()函數(shù)實(shí)現(xiàn)簡(jiǎn)單輪詢(xún)操作的方法,以實(shí)例形式分析了輪詢(xún)操作的原理與javascript實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-02-02
JavaScript判斷兩個(gè)數(shù)組相等的4類(lèi)方法總結(jié)
如果我們需要比較兩個(gè)數(shù)組是否相等,不能像比較基本類(lèi)型(String、Number、Boolean等)一樣,使用 === (或 ==) 來(lái)判斷,所以如果要比較數(shù)組是否相等,需要使用一些特殊方法。本文為大家整理了四種常見(jiàn)用法,需要的可以參考一下2023-02-02
javascript 二維數(shù)組的實(shí)現(xiàn)與應(yīng)用
javascript沒(méi)有二維數(shù)組.所有自定義了一個(gè)數(shù)組類(lèi),下面是實(shí)例代碼,需要的朋友可以參考下。2010-03-03
如何在一段文字里點(diǎn)一下就可以在里面插入一段文字?
如何在一段文字里點(diǎn)一下就可以在里面插入一段文字?...2007-01-01
原生js實(shí)現(xiàn)的貪吃蛇網(wǎng)頁(yè)版游戲完整實(shí)例
這篇文章主要介紹了原生js實(shí)現(xiàn)的貪吃蛇網(wǎng)頁(yè)版游戲完整實(shí)例,可實(shí)現(xiàn)自主選擇游戲難度進(jìn)行貪吃蛇游戲的功能,涉及javascript鍵盤(pán)事件及頁(yè)面元素的操作技巧,需要的朋友可以參考下2015-05-05
JS實(shí)現(xiàn)"上次操作未完成禁止新操作"邏輯特事特辦方案
這篇文章主要介紹了詳解JS如何實(shí)現(xiàn)"上次操作未完成禁止新操作"的邏輯及思路,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
微信小程序h5頁(yè)面跳轉(zhuǎn)小程序的超詳細(xì)講解
開(kāi)發(fā)中涉及到一個(gè)需求,就是從一個(gè)預(yù)約票購(gòu)買(mǎi)的頁(yè)面需要跳轉(zhuǎn)到?小程序,下面這篇文章主要給大家介紹了關(guān)于微信小程序h5頁(yè)面跳轉(zhuǎn)小程序的超詳細(xì)講解,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02

