diff --git a/src/views/ebiz/saleFlowProImprove/components/fab.vue b/src/views/ebiz/saleFlowProImprove/components/fab.vue index b6fac4e23..2b70531dc 100644 --- a/src/views/ebiz/saleFlowProImprove/components/fab.vue +++ b/src/views/ebiz/saleFlowProImprove/components/fab.vue @@ -30,18 +30,20 @@ export default { data() { return { - isDragging: false, - hasDragged: false, // 新增:标记是否发生了拖拽 - startX: 0, - startY: 0, - posX: 0, - posY: 0, - windowWidth: 0, - windowHeight: 0, - fabWidth: 0, - fabHeight: 0, - initialX: 0, - initialY: 0 + isDragging: false, // 是否正在拖动 + hasDragged: false, // 是否发生了拖拽 + startX: 0, // 触摸点相对于元素左上角的X偏移 + startY: 0, // 触摸点相对于元素左上角的Y偏移 + posX: 0, // 元素当前位置X + posY: 0, // 元素当前位置Y + initialTouchX: 0, // 初始触摸点X + initialTouchY: 0, // 初始触摸点Y + windowWidth: 0, // 视口宽度 + windowHeight: 0, // 视口高度 + fabWidth: 0, // FAB宽度 + fabHeight: 0, // FAB高度 + initialX: 0, // 初始位置X + initialY: 0 // 初始位置Y } }, @@ -79,6 +81,9 @@ export default { }, methods: { + /** + * 更新窗口大小 + */ updateWindowSize() { this.windowWidth = window.innerWidth this.windowHeight = window.innerHeight @@ -90,89 +95,128 @@ export default { } }, + /** + * 开始拖动 + * @param event {TouchEvent} + */ startDrag(event) { if (!this.draggable) return + // 阻止默认行为(如页面滚动)和事件冒泡 + event.preventDefault() + event.stopPropagation() + + const touch = event.touches[0] + + // 记录初始触摸位置 + this.initialTouchX = touch.clientX + this.initialTouchY = touch.clientY + + // 记录元素当前位置和触摸点的偏移 + this.startX = touch.clientX - this.posX + this.startY = touch.clientY - this.posY + + // 设置拖动状态 this.isDragging = true this.hasDragged = false - const clientX = event.touches ? event.touches[0].clientX : event.clientX - const clientY = event.touches ? event.touches[0].clientY : event.clientY - - this.startX = clientX - this.posX - this.startY = clientY - this.posY - + // 禁用文本选择 document.body.style.userSelect = 'none' - - const options = { passive: false } - document.addEventListener('mousemove', this.onDrag, options) - document.addEventListener('touchmove', this.onDrag, options) - document.addEventListener('mouseup', this.stopDrag, options) - document.addEventListener('touchend', this.stopDrag, options) + document.body.style.webkitUserSelect = 'none' }, + /** + * 拖动中 + * @param event { TouchEvent } + */ onDrag(event) { if (!this.isDragging) return - this.hasDragged = true + // 阻止默认行为(如页面滚动) + event.preventDefault() + event.stopPropagation() - const clientX = event.touches ? event.touches[0].clientX : event.clientX - const clientY = event.touches ? event.touches[0].clientY : event.clientY + // 获取当前触摸点 + const touch = event.touches[0] - let newX = clientX - this.startX - let newY = clientY - this.startY + // 计算新位置(相对于初始触摸点的偏移) + let newX = touch.clientX - this.startX + let newY = touch.clientY - this.startY + // 应用边界限制 if (this.boundary) { - newX = Math.max(0, Math.min(newX, this.windowWidth - this.fabWidth)) - newY = Math.max(0, Math.min(newY, this.windowHeight - this.fabHeight)) + const maxX = this.windowWidth - this.fabWidth + const maxY = this.windowHeight - this.fabHeight + + // 确保不会移出视口 + newX = Math.max(0, Math.min(newX, maxX)) + newY = Math.max(0, Math.min(newY, maxY)) } + // 使用transform实现平滑移动 this.posX = newX this.posY = newY + + // 标记为已拖动,防止点击事件触发 + if (Math.abs(touch.clientX - this.initialTouchX) > 5 || Math.abs(touch.clientY - this.initialTouchY) > 5) { + this.hasDragged = true + } }, + /** + * 拖动结束 + * @param event { TouchEvent } + */ stopDrag(event) { if (!this.isDragging) return this.isDragging = false document.body.style.userSelect = '' + this.removeEventListeners() - // 如果是拖拽结束,阻止后续的点击事件 - if (this.hasDragged) { - // 延迟重置标志位,确保不会触发点击事件 - setTimeout(() => { - this.hasDragged = false - }, 100) + // 阻止事件冒泡,避免触发父元素的点击事件 + if (event) { + event.stopPropagation() + event.preventDefault() } - this.removeEventListeners() this.$emit('drag-end', { x: this.posX, y: this.posY }) }, + /** + * 点击事件 + * @param event { TouchEvent } + */ handleClick(event) { // 如果是拖拽操作,不触发点击事件 - if (this.isDragging || this.hasDragged) { + if (this.hasDragged) { event.stopPropagation() + event.preventDefault() this.hasDragged = false - return + return false } this.$emit('click', event) + return true }, + /** + * 移除事件监听器 + */ removeEventListeners() { - const options = { passive: false } - document.removeEventListener('mousemove', this.onDrag, options) - document.removeEventListener('touchmove', this.onDrag, options) - document.removeEventListener('mouseup', this.stopDrag, options) - document.removeEventListener('touchend', this.stopDrag, options) + // 恢复用户选择 + document.body.style.userSelect = '' + document.body.style.webkitUserSelect = '' + + // 重置拖动状态 + this.isDragging = false } } }