如何在jQuery中实现滑动元素的显示与拖拽隐藏功能?
解决拖拽关闭底部弹窗的问题
原代码核心问题
- 同时混用
top和bottom属性控制弹窗定位,导致拖拽与隐藏逻辑冲突 - 阈值判断依赖弹窗
top偏移量,无法准确识别有效拖拽距离 - 隐藏弹窗时未设置目标
bottom:-100%属性,仅清空top无法触发隐藏动画 - 拖拽过程中保留过渡效果,导致操作卡顿
修正后的实现代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <button>click here</button> <div class="popup">drag me down to dismiss me</div>
CSS
.popup{ width:100%; height:80%; background: blue; position:fixed; bottom:-100%; color:white; transition: bottom 0.3s ease-in-out; /* 统一过渡效果 */ }
JavaScript
let isDragging = false; let startY; const draggableModals = $('.popup'); const threshold = 150; // 调整触发隐藏的拖拽距离阈值 const startDrag = (e) => { isDragging = true; // 记录拖拽起始点Y坐标 startY = e.originalEvent.touches ? e.originalEvent.touches[0].clientY : e.clientY; // 拖拽时移除过渡,避免卡顿 draggableModals.css('transition', 'none'); }; const doDrag = (e) => { if (!isDragging) return; const clientY = e.originalEvent.touches ? e.originalEvent.touches[0].clientY : e.clientY; // 计算向下拖拽的位移量(正值为向下) const deltaY = clientY - startY; draggableModals.each(function () { // 计算当前bottom值:显示状态为0,向下拖拽时bottom为负位移值,限制最小为-弹窗高度 const currentBottom = Math.max(-$(this).outerHeight(), -deltaY); $(this).css('bottom', `${currentBottom}px`); }); }; const stopDrag = () => { if (!isDragging) return; isDragging = false; // 恢复过渡效果 draggableModals.css('transition', 'bottom 0.3s ease-in-out'); draggableModals.each(function () { const $modal = $(this); // 通过bottom值反推实际拖拽距离 const dragDistance = -parseInt($modal.css('bottom')); // 拖拽距离超过阈值则隐藏,否则回弹显示 if (dragDistance > threshold) { $modal.css('bottom', '-100%'); } else { $modal.css('bottom', '0'); } }); }; // 绑定拖拽事件 draggableModals.on('mousedown touchstart', startDrag); $(document).on('mousemove touchmove', doDrag); $(document).on('mouseup touchend', stopDrag); // 点击按钮显示弹窗 $(document).on('click', 'button', function(){ $('.popup').css('bottom', 0); });
关键修改说明
- 统一
bottom属性控制:全程用bottom管理弹窗位置,避免与top属性冲突,匹配初始设计逻辑 - 拖拽时移除过渡:开始拖拽时临时移除过渡效果,保证操作流畅,停止拖拽后恢复过渡
- 精准位移计算:通过拖拽位移动态调整
bottom值,同时限制拖拽范围避免超出屏幕 - 阈值判断优化:通过
bottom值反推实际拖拽距离,超过阈值触发隐藏,否则回弹显示
内容的提问来源于stack exchange,提问作者drago
相关产品推荐
相关产品推荐

