如何为通知框添加左滑显示删除按钮的Swipe Effect
如何实现通知栏左滑显示删除按钮的交互效果
需求:为每条通知栏添加左滑交互,左滑后在通知末尾显示删除按钮,效果类似苹果短信的左滑删除功能,预期效果如下:

原HTML结构如下:
<div class="spacer"> <p class="header-text">Notifications</p> <div class="grey-box"> <p class="grey-box-text">Today</p> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Notification Name</p> <p class="notification-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna.</p> <p class="notification-time-label">2h ago</p> </div> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Link To Our Survey</p> <p class="notification-content">Lorem ipsum dolor sit amet, consectetur: <br> <a href="www.survey-generator.com/293/39djd" class="notification-link"> www.survey-generator.com/293/39djd</a></p> <p class="notification-time-label">2h ago</p> </div> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Notification Name</p> <p class="notification-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna.</p> <p class="notification-time-label">2h ago</p> </div> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Claim Status Update</p> <p class="notification-content">Your claim #230291 has been moved to “Under Review” Status... to view more go to Claims Tab.</p> <p class="notification-time-label">3h ago</p> </div> </div> <div class="grey-box"> <p class="grey-box-text">Previous</p> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Notification Name</p> <p class="notification-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna.</p> <p class="notification-time-label">2h ago</p> </div> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Link To Our Survey</p> <p class="notification-content">Lorem ipsum dolor sit amet, consectetur: <br> <a href="www.survey-generator.com/293/39djd" class="notification-link"> www.survey-generator.com/293/39djd</a> </p> <p class="notification-time-label">2h ago</p> </div> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Notification Name</p> <p class="notification-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit ut aliquam, purus sit amet luctus venenatis, lectus magna fringilla urna.</p> <p class="notification-time-label">2h ago</p> </div> </div> <div class="notification-box"> <div class="notification-icon"> <i class="far fa-calendar icon"></i> </div> <div class="notification-content-box"> <p class="notification-title">Claim Status Update</p> <p class="notification-content">Your claim #230291 has been moved to “Under Review” Status... to view more go to Claims Tab.</p> <p class="notification-time-label">3h ago</p> </div> </div> </div>
实现方案
1. 修改HTML结构
给每个notification-box包裹一层滑动容器,同时添加删除按钮:
<!-- 替换原单个notification-box为以下结构 --> <div class="swipe-container"> <div class="notification-box"> <!-- 原通知内容保持不变 --> </div> <button class="delete-btn">删除</button> </div>
2. 添加CSS样式
设置滑动容器布局、过渡动画及删除按钮样式:
.swipe-container { position: relative; display: flex; overflow: hidden; margin-bottom: 12px; } .notification-box { flex: 1; display: flex; align-items: flex-start; padding: 15px; background: #fff; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); cursor: grab; } .delete-btn { width: 85px; background: #ff3b30; color: #fff; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 14px; } .notification-box.dragging { cursor: grabbing; }
3. 编写JavaScript交互逻辑
监听鼠标/触摸事件,实现滑动判断、位移控制及删除功能:
const swipeContainers = document.querySelectorAll('.swipe-container'); swipeContainers.forEach(container => { const notificationBox = container.querySelector('.notification-box'); const deleteBtn = container.querySelector('.delete-btn'); let startX = 0; let currentX = 0; let isDragging = false; const deleteBtnWidth = deleteBtn.offsetWidth; // 鼠标事件绑定 notificationBox.addEventListener('mousedown', startDrag); document.addEventListener('mousemove', drag); document.addEventListener('mouseup', endDrag); // 触摸事件绑定 notificationBox.addEventListener('touchstart', startDrag); document.addEventListener('touchmove', drag); document.addEventListener('touchend', endDrag); function startDrag(e) { isDragging = true; notificationBox.classList.add('dragging'); // 兼容鼠标和触摸事件的起始位置获取 startX = e.type === 'touchstart' ? e.touches[0].clientX : e.clientX; } function drag(e) { if (!isDragging) return; e.preventDefault(); currentX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX; const diffX = startX - currentX; // 限制仅向左滑动,且位移不超过删除按钮宽度 if (diffX > 0 && diffX <= deleteBtnWidth) { notificationBox.style.transform = `translateX(-${diffX}px)`; } else if (diffX > deleteBtnWidth) { notificationBox.style.transform = `translateX(-${deleteBtnWidth}px)`; } } function endDrag() { if (!isDragging) return; isDragging = false; notificationBox.classList.remove('dragging'); const diffX = startX - currentX; // 滑动超过一半宽度时固定展开,否则回弹复位 if (diffX > deleteBtnWidth / 2) { notificationBox.style.transform = `translateX(-${deleteBtnWidth}px)`; } else { notificationBox.style.transform = 'translateX(0)'; } // 删除按钮点击事件 deleteBtn.addEventListener('click', () => { container.style.opacity = '0'; container.style.transform = 'translateX(-100%)'; container.style.transition = 'all 0.3s ease'; setTimeout(() => container.remove(), 300); }); } });
效果说明
- 同时支持鼠标拖拽和触摸滑动两种操作方式
- 左滑距离超过删除按钮一半宽度时,自动固定显示删除按钮;否则平滑回弹复位
- 点击删除按钮后,通知条会向左滑出并移除DOM
内容的提问来源于stack exchange,提问作者hopetocodebetter
相关产品推荐
相关产品推荐

