基於jQuery的左滑出現刪除按鈕
最近在做專案的時候遇到了個需求,在網頁上實現類似於QQ會話列表那樣子的左滑出現刪除按鈕的效果,於是嘗試著寫了一個,寫出來與大家交流分享,大神勿噴。
基本要求
由於我們是在做一個跨平臺的APP,裡面部分介面其實就是WebView載入的網頁,因此需要使用網頁實現這樣的效果:往左滑動時,顯示刪除按鈕,再往右滑,隱藏刪除按鈕。
成品示例圖
額,先上圖吧。下面分別是在PC瀏覽器裡和在Mobile瀏覽器裡的效果。
PC瀏覽器
手機瀏覽器
實現思路
為了說明我的實現思路,做了兩個圖來輔助說明。
首先,請看圖1。在圖中,我們設定每一行的寬度超過瀏覽器的寬度,其超出的部分就是放置按鈕的區域。由於超出了瀏覽器的最大寬度,因此按鈕區域此時是不可見的,只能顯示左側的常規資訊部分。
圖1 普通狀態
接下來,我們監聽左側常規資訊區域,監聽滑動事件(具體如何監聽先不考慮)。當我們監聽到左滑事件時,我們讓相應行左偏移,讓按鈕顯示出來,同時左側超出的部分被遮擋(請看圖2)。
圖2 左滑狀態
當我們右滑時,我們再讓相應行回覆到左偏移為0的時候就行了。
關鍵實現方式
- 對於左滑和右滑,我們通過設定常規資訊區域的marin-left來實現,當設定margin-left為負值時,實現左滑,當再次設定margin-left為0時,實現右滑。
- 對於滑動事件監聽,通過監聽滑鼠(手指)按下和擡起來實現,根據兩點的X座標的差值的正負判定是右滑還是左滑。
完整程式碼
需要注意的是,我在測試的時候用的是chrome的普通模式和mobile模擬器模式,發現兩種模式下監聽是不一樣的,因此我寫了兩種監聽,這樣至少有一種會執行。也許有其他更好的適配方法,但不作為此處的重點。當然也歡迎大家賜教。
至於程式碼部分,用了jQuery,其實不用也沒啥問題的,動畫滑動和監聽都可以用純js寫,但是由於這不是這裡的重點,那麼為什麼不用jQuery呢?成功者站在巨人的肩膀上,而且咱也沒有jQuery寫的好 (。・`ω´・)
2015/11/13更新
有位同學提出說程式碼在QQ手機瀏覽器和Opera手機瀏覽器等中沒有滑動效果,找了一下大概是這個帖子http://bbs.mb.qq.com/thread-201794-1-1.html
// 橫向位移大於縱向位移,阻止縱向滾動
if (Math.abs(delta.x) > Math.abs(delta.y)) {
event.preventDefault();
}
2016/02/25更新
qq_25558115同學提到:“如果再能給大家提供出只能有一條記錄可以左滑, 倘若滑動其他的記錄,則有左滑記錄的要回到原位”。於是進行了簡單實現。主要思路如下:
// 用一個變數記錄上一次左滑的物件
var lastLeftObj;
// 在左滑發生的時候,判定上一個左滑的物件是否存在,若存在,且不是當前被左滑的物件,則將其右滑
// 同時,記錄新的左滑物件
// 在右滑發生時,將上一個左滑物件清空
if (左滑) {
pressedObj左滑
lastLeftObj && lastLeftObj != pressedObj && lastLeftObj右滑
lastLeftObj = pressedObj; // 記錄上一個左滑的物件
} else if (右滑) {
pressedObj右滑
lastLeftObj = null; // 清空上一個左滑的物件
}
2016/09/06更新
根據馬燦發同學提出的bug進行修改:
右滑時進行判斷,僅當要右滑的物件(pressedObj)是上一次左滑的物件(lastLeftObj)時才將物件右滑並清空lastLeftObj。
if (pressedObj == lastLeftObj) {...}
根據girlyougo同學的提議,新增“在除本行外的其他區域點選時均復位當前左滑按鈕”的功能。思路為在滑動結束時,判定pressedObj!=lastLeftObj
,即可知點選/滑動的物件為其他物件:
// 點選除當前左滑物件之外的任意其他位置
if (lastLeftObj && pressedObj != lastLeftObj) {
$(lastLeftObj).animate({marginLeft:"0"}, 500); // 右滑
lastLeftObj = null; // 清空上一個左滑的物件
}
實際上,在添加了上述功能之後,前面提到的bug不存在了。不過此處保留了消除bug的那部分程式碼。
更新後的完整程式碼如下:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>左劃出現刪除按鈕,右滑隱藏</title>
<script type="text/javascript" src="jquery-1.11.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e) {
// 設定每一行的寬度=螢幕寬度+按鈕寬度
$(".line-scroll-wrapper").width($(".line-wrapper").width() + $(".line-btn-delete").width());
// 設定常規資訊區域寬度=螢幕寬度
$(".line-normal-wrapper").width($(".line-wrapper").width());
// 設定文字部分寬度(為了實現文字過長時在末尾顯示...)
$(".line-normal-msg").width($(".line-normal-wrapper").width() - 280);
// 獲取所有行,對每一行設定監聽
var lines = $(".line-normal-wrapper");
var len = lines.length;
var lastX, lastXForMobile;
// 用於記錄被按下的物件
var pressedObj; // 當前左滑的物件
var lastLeftObj; // 上一個左滑的物件
// 用於記錄按下的點
var start;
// 網頁在移動端執行時的監聽
for (var i = 0; i < len; ++i) {
lines[i].addEventListener('touchstart', function(e){
lastXForMobile = e.changedTouches[0].pageX;
pressedObj = this; // 記錄被按下的物件
// 記錄開始按下時的點
var touches = event.touches[0];
start = {
x: touches.pageX, // 橫座標
y: touches.pageY // 縱座標
};
});
lines[i].addEventListener('touchmove',function(e){
// 計算划動過程中x和y的變化量
var touches = event.touches[0];
delta = {
x: touches.pageX - start.x,
y: touches.pageY - start.y
};
// 橫向位移大於縱向位移,阻止縱向滾動
if (Math.abs(delta.x) > Math.abs(delta.y)) {
event.preventDefault();
}
});
lines[i].addEventListener('touchend', function(e){
if (lastLeftObj && pressedObj != lastLeftObj) { // 點選除當前左滑物件之外的任意其他位置
$(lastLeftObj).animate({marginLeft:"0"}, 500); // 右滑
lastLeftObj = null; // 清空上一個左滑的物件
}
var diffX = e.changedTouches[0].pageX - lastXForMobile;
if (diffX < -150) {
$(pressedObj).animate({marginLeft:"-132px"}, 500); // 左滑
lastLeftObj && lastLeftObj != pressedObj &&
$(lastLeftObj).animate({marginLeft:"0"}, 500); // 已經左滑狀態的按鈕右滑
lastLeftObj = pressedObj; // 記錄上一個左滑的物件
} else if (diffX > 150) {
if (pressedObj == lastLeftObj) {
$(pressedObj).animate({marginLeft:"0"}, 500); // 右滑
lastLeftObj = null; // 清空上一個左滑的物件
}
}
});
}
// 網頁在PC瀏覽器中執行時的監聽
for (var i = 0; i < len; ++i) {
$(lines[i]).bind('mousedown', function(e){
lastX = e.clientX;
pressedObj = this; // 記錄被按下的物件
});
$(lines[i]).bind('mouseup', function(e){
if (lastLeftObj && pressedObj != lastLeftObj) { // 點選除當前左滑物件之外的任意其他位置
$(lastLeftObj).animate({marginLeft:"0"}, 500); // 右滑
lastLeftObj = null; // 清空上一個左滑的物件
}
var diffX = e.clientX - lastX;
if (diffX < -150) {
$(pressedObj).animate({marginLeft:"-132px"}, 500); // 左滑
lastLeftObj && lastLeftObj != pressedObj &&
$(lastLeftObj).animate({marginLeft:"0"}, 500); // 已經左滑狀態的按鈕右滑
lastLeftObj = pressedObj; // 記錄上一個左滑的物件
} else if (diffX > 150) {
if (pressedObj == lastLeftObj) {
$(pressedObj).animate({marginLeft:"0"}, 500); // 右滑
lastLeftObj = null; // 清空上一個左滑的物件
}
}
});
}
});
</script>
<style type="text/css">
* { margin: 0; padding: 0; }
.line-wrapper { width: 100%; height: 144px; overflow: hidden; font-size: 28px; border-bottom: 1px solid #aaa; }
.line-scroll-wrapper { white-space: nowrap; height: 144px; clear: both; }
.line-btn-delete { float: left; width: 132px; height: 144px; }
.line-btn-delete button { width: 100%; height: 100%; background: red; border: none; font-size: 24px; font-family: 'Microsoft Yahei'; color: #fff; }
.line-normal-wrapper { display: inline-block; line-height: 100px; float: left; padding-top: 10px; padding-bottom: 10px; }
.line-normal-icon-wrapper { float: right; width: 120px; height: 120px; margin-right: 12px; }
.line-normal-icon-wrapper img { width: 120px; height: 120px; }
.line-normal-avatar-wrapper { width: 100px; height: 124px; float: left; margin-left: 12px; }
.line-normal-avatar-wrapper img { width: 92px; height: 92px; border-radius: 60px; }
.line-normal-left-wrapper { float: left; overflow: hidden; }
.line-normal-info-wrapper { float: left; margin-left: 10px; }
.line-normal-user-name { height: 28px; line-height: 28px; color: #4e4e4e; margin-top: 7px; }
.line-normal-msg { height: 28px; line-height: 28px; overflow:hidden; text-overflow:ellipsis; color: #4e4e4e; margin-top: 11px; }
.line-normal-time { height: 28px; line-height: 28px; color: #999; margin-top: 11px; }
</style>
</head>
<body>
<div class="line-wrapper">
<div class="line-scroll-wrapper">
<div class="line-normal-wrapper">
<div class="line-normal-left-wrapper">
<div class="line-normal-avatar-wrapper"><img src="1.jpg" /></div>
<div class="line-normal-info-wrapper">
<div class="line-normal-user-name">蠟筆小新</div>
<div class="line-normal-msg">在同行的小夥伴中提到了你</div>
<div class="line-normal-time">1分鐘前</div>
</div>
</div>
<div class="line-normal-icon-wrapper"><img src="5.jpg"/></div>
</div>
<div class="line-btn-delete"><button>刪除</button></div>
</div>
</div>
<div class="line-wrapper">
<div class="line-scroll-wrapper">
<div class="line-normal-wrapper">
<div class="line-normal-left-wrapper">
<div class="line-normal-avatar-wrapper"><img src="2.jpg" /></div>
<div class="line-normal-info-wrapper">
<div class="line-normal-user-name">喬巴</div>
<div class="line-normal-msg">你看不到我哦</div>
<div class="line-normal-time">1分鐘前</div>
</div>
</div>
<div class="line-normal-icon-wrapper"><img src="6.jpg"/></div>
</div>
<div class="line-btn-delete"><button>刪除</button></div>
</div>
</div>
<div class="line-wrapper">
<div class="line-scroll-wrapper">
<div class="line-normal-wrapper">
<div class="line-normal-left-wrapper">
<div class="line-normal-avatar-wrapper"><img src="3.jpg" /></div>
<div class="line-normal-info-wrapper">
<div class="line-normal-user-name">賤行賤遠</div>
<div class="line-normal-msg">回憶裡想起模糊的小時候,雲朵漂浮在藍藍的天空,那時的你說,要和我手牽手,一起走到時間的盡頭</div>
<div class="line-normal-time">1分鐘前</div>
</div>
</div>
<div class="line-normal-icon-wrapper"><img src="7.jpg"/></div>
</div>
<div class="line-btn-delete"><button>刪除</button></div>
</div>
</div>
<div class="line-wrapper">
<div class="line-scroll-wrapper">
<div class="line-normal-wrapper">
<div class="line-normal-left-wrapper">
<div class="line-normal-avatar-wrapper"><img src="4.png" /></div>
<div class="line-normal-info-wrapper">
<div class="line-normal-user-name">小黃人</div>
<div class="line-normal-msg">哈哈哈哈哈……暑假來看小黃人電影哦~哈哈哈……</div>
<div class="line-normal-time">1分鐘前</div>
</div>
</div>
<div class="line-normal-icon-wrapper"><img src="8.jpg"/></div>
</div>
<div class="line-btn-delete"><button>刪除</button></div>
</div>
</div>
</body>
</html>
總結
程式碼還比較粗糙,存在很多bug,也有些地方不是那麼絕對。比如當我按下時是在第一條記錄,然後擡起時是在第二條記錄,那麼這時候滑動將是第一條記錄。但是這個看具體需求了,如果你覺得滑動的物件應該以按下去時的物件為準的話,那就不管在哪擡起都滑動那個按下時的物件;如果你覺得滑動的物件應該是擡起時的物件,那也沒問題,或者你覺得按下和擡起時不是同一個物件就不滑動任何物件那也行。總之,看需求。
大家可以下載原始碼試一試哈~
原始碼請戳:原始碼下載
// 個人學習記錄,大神勿噴
// [email protected]
// 2015/6/5
// 最後更新 2016/9/6
相關推薦
基於jQuery的左滑出現刪除按鈕
最近在做專案的時候遇到了個需求,在網頁上實現類似於QQ會話列表那樣子的左滑出現刪除按鈕的效果,於是嘗試著寫了一個,寫出來與大家交流分享,大神勿噴。 基本要求 由於我們是在做一個跨平臺的APP,裡面部分介面其實就是WebView載入的網頁,因此需要使用網頁
左劃出現刪除按鈕,右滑隱藏
<!doctype html> <html> <head> <meta charset="utf-8"> <title>左劃出現刪除按鈕,右滑隱藏</title> <script src="http://lib
Android仿QQ和iOS的ListView左滑出現刪除和置頂等操作,可自定義選單
一:介紹 大家在專案中可能會有對ListView向左滑動的時候出現刪除,置頂等等操作的需求,例如QQ聊天列表左滑,iOS中左滑刪除等等,下面就介紹一下如何實現這種效果 二:先給大家展示效果圖,先睹為快 三:實現步驟 1.這種效果的ListView是自定義的控制元件,開源庫的下載地址是
Android 實現左滑出現刪除選項
滑動刪除的部分主要包含兩個部分, 一個是內容區域(用於放置正常顯示的view),另一個是操作區域(用於放置刪除按鈕)。預設情況下,操作區域是不顯示的,內容區域的大小是填充整個容 器,操作區域始終位於內容區域的右面。當開始滑動的時候,整個容器中的所有子view都像
左滑tableview出現刪除按鈕
首先在tableView裡面實現cell的左滑刪除功能是挺簡單的,相信大家都懂得怎麼做。但是,當有多個tableView放在一個scrollView裡面的時候,會產生一系列的問題。 問題1: scrollView在滑倒最邊上(左或右)的時候,為了提醒使用者已經滑到最邊上了(左或右),再繼續向左(
關於tableview的知識總結,cell左劃出現刪除、置頂按鈕
tableview是一個表檢視控制元件,在ios開發過程中用處最多的一個控制元件。它繼承與UIScrollView,有兩種樣式 UITableViewStyleGrouped和UITableViewStylePlain。使用表檢視必須遵循UITableViewDataSou
左滑操作(刪除,置頂等。。。)
在滑動列表中,常常會有左滑出現刪除,置頂操作的需求,如下qq的左滑效果: 今天也來實現下類似的效果,可供大家參考: 1.實現原理 原理圖 2.實現自定義左滑View 1.新增View 首先在自定義V
tableView左滑 編輯 刪除或其他操作
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { return YES; //tableView可編輯 } -
使用MUI 實現模仿QQ向左滑動出現刪除,編輯的程式碼
/* 使出現的錯誤隱藏[Intervention] Unable to preventDefault inside passive event listener due to target being treated as */
去除input輸入框預設在ie或者edge下出現刪除按鈕
當使用input輸入框的時候,預設情況下在後面會出現刪除按鈕,這個時候需要程式碼去去除,去除ie下的刪除按鈕程式碼如下: ::-ms-clear{display: none;} ::-ms-reveal{display: none;} 去除edge下的刪除按鈕程式
基於JQuery的購物車新增刪除以及結算功能
前段時間瞭解到購物車結算算是一個難點部分,在網上也找了一些,但是網上除了外掛之外,就是一些半成品,比如一部分只有新增刪除效果,另一部分只有結算功能,很少見到整合在一起的購物車效果,因此自己寫了一個,方便大家檢視 (新增效果沒有飛入,實在懶得寫動畫效果了,湊合看吧) HTM
仿ios簡訊列表滑動出現刪除按鈕
最近還沒找到工作所以在宿舍有點閒,所以呢就自己寫了這麼一個例子。之前網上有很多人寫過類似的文章或demo,github上面也有開源專案。但是,老是copy別人程式碼也怪沒意思的,於是就自己嘗試著自己寫唄。廢話多了先來看下效果咯: 執行效果: 1、實現思路
用ionic做的列表向左滑動,出現刪除等功能按鈕
ann 需要 balance -o tails details edate sts tran 廢話不多說,直接上代碼 html代碼: <!--列表--><ul class="lists" ng-repeat="list in lists"> <
仿QQ左滑刪除【基於RecyclerView】
這是我github開源專案,目前測試階段,歡迎大家使用提意見! https://github.com/SineyCoder/LeftSlideView 使用步驟 新增倉庫 allprojects { rep
自定義UITableView實現自定義左滑刪除按鈕及多按鈕,拖拽cell和表頭進行排序
本文介紹了能拖拽cell和表頭進行排序的自定義UITableView,並且能自定義左滑顯示的UIButton樣式。 先看左滑自定義按鈕效果圖 : override func tableView(_ tableView: UITableView, editA
jQuery實現移動端左滑刪除功能
在手機移動端,經常需要實現類似微信聊天工具中的左滑動刪除和右滑動恢復功能。 這裡,我們可以直接使用jQuery來實現該效果。 基本原理: 利用jQuery中的touchstart、touchmo
基於JS實現移動端左滑刪除功能
HTML <div class="wrap pay-wrap" id="lists"> @foreach (var item in Model) { <div class="pay-list" style="h
左滑菜單(刪除、置頂)
gin 所有 nbsp func stl lis mod cli img <div class="xinzhibox"> <div class="list"> <div class="xinzhilis
ionic之左滑刪除
scala link rep false clas itl reat edi repeat <html ng-app="ionicApp"> <head> <meta charset="utf-8"> <meta name
前端 html h5 移動端 手機端 仿ios左滑刪除效果
es2017 b- open translate def sna 技術 9.png replace 實現功能:左滑列表項(<li class="route-item" ></li>),出現刪除按鈕(<div class="removeJs"&