移动端左滑删除功能,超过删除按钮40%的宽度,滑至目标点,否则回弹。
主要思路为在元素上添加了data-type 来标志它的位置,滑到目标位置为 “1”,原点为 “0”;这样就可以在原点和目标点滑动时
都可以做回弹的效果。现在的代码感觉比较复杂了,应该有更简单的方法实现,还会持续修改和完善。
代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> *{ padding: 0; margin: 0; } .box{ width: 100%; } .move:nth-of-type(1){ margin-top: 0 } .move{ width: 100%; height: 50px; position: relative; margin-top: 10px; } .cover{ width: 100%; height: 100%; background: orange; position: relative; z-index: 5; } .del{ width: 80px; height: 100%; position: absolute; right: 0; top: 0; background: red; text-align: center; line-height: 50px; color: #fff; font-size: 24px; } </style> </head> <body> <div class="box"> <div class="move"> <div class="cover" data-type="0"></div> <div class="del">删除</div> </div> <div class="move"> <div class="cover" data-type="0"></div> <div class="del">删除</div> </div> </div> <script> let move = document.getElementsByClassName('move') let cover = document.getElementsByClassName('cover') let box = document.getElementsByClassName('box')[0] //删除按钮的宽度 let w = document.getElementsByClassName('del')[0].offsetWidth let startX = 0, moveX = 0, deltaX = 0,x //元素循环绑定touch事件 for (let i = 0; i < cover.length; i++) { cover[i].addEventListener('touchstart', function(e){ let point = e.touches ? e.touches[0] : e startX = point.pageX //pageX 从左到右是0-max }) cover[i].addEventListener('touchmove', function(e){ let point = e.touches ? e.touches[0] : e moveX = point.pageX deltaX = moveX - startX //开始不能往右滑动,即deltaX最大为0 //最终不能滑动超过w的宽度,即 deltaX最小不能小于-w if (deltaX <= 0) { //左滑 if (cover[i].dataset.type === "0") { //如果data-type === 0 向左滑动 最大宽度为w //touchend 当滑动超过 w * 0.4 时,会滑动到最大位置 -w 对应的data-type 改为 1 if (Math.abs(deltaX) < w) { cover[i].style.transform = `translateX(${deltaX}px)` } } else { //如果data-type !== 0 意味着此时已经处于左滑的最大位置,此时向左滑动时,最大值就是 -w cover[i].style.transform = `translateX(${-w}px)` } } else { //右滑 右滑与左滑是同样的道理 if(cover[i].dataset.type === "0") { //data-type === 0 即还在初始位置,初始位置向右滑动距离为0 cover[i].style.transform = `translateX(0px)` } else { if (Math.abs(deltaX) < w) { cover[i].style.transform = `translateX(-${w-Math.abs(deltaX)}px)` } } } }) cover[i].addEventListener('touchend', function(e){ let tmp = w * 0.4 let x = Math.abs(deltaX) if (cover[i].dataset.type === "0") { if (deltaX >= 0) { // data-type === 0 在初始位置 deltaX 为正 向右滑动 要求滑动距离为 0 cover[i].style.transform = `translateX(0px)` cover[i].style.transition = '' } else { //滑动距离大于 tmp; 就滑动到底,否则回弹 if (x > tmp) { cover[i].style.transform = `translateX(${-w}px)` cover[i].dataset.type = "1" } else { cover[i].style.transform = `translateX(0px)` } cover[i].style.transition = 'all 0.3s' } } else { if (deltaX <= 0) { // data-type === 1 在左滑最大位置 deltaX 为负 向左滑动 要求滑动距离为 0 cover[i].style.transform = `translateX(${-w}px)` cover[i].style.transition = '' } else { if (x > tmp) { cover[i].style.transform = `translateX(0px)` cover[i].dataset.type = "0" } else { cover[i].style.transform = `translateX(${-w}px)` } cover[i].style.transition = 'all 0.3s' } } }) } </script> </body> </html>
如果不追求滑到目标点以后,往回滑动的回弹效果还有个比较简单的处理滑动距离的方法:
let x = Math.min(0, Math.max(-btnWidth, deltaX)) //btnWidth是删除按钮的宽度,x就是移动距离