20260908223921
This commit is contained in:
1 parent
8734b43a2a
commit
ead8e66626
60 files changed
+562
-8502
No files matched your search
@@ -47,9 +47,28 @@ watch(isPassing, (val) => {
|
||||
|
||||
/* ================= 拖拽逻辑 ================= */
|
||||
function getEventPageX(e) {
|
||||
if ('pageX' in e) return e.pageX
|
||||
if ('touches' in e && e.touches[0]) return e.touches[0].pageX
|
||||
return 0
|
||||
if (typeof e.pageX === 'number') return e.pageX
|
||||
// touchend 事件没有 touches,需要取 changedTouches,否则会误判为拖到 0 而回退
|
||||
const touch = e.changedTouches?.[0] || e.touches?.[0]
|
||||
return touch ? touch.pageX : 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽中把 move 事件挂到 document 上:
|
||||
* 只挂在组件根节点时,鼠标移出组件后收不到 mousemove,滑块会卡在原地。
|
||||
*/
|
||||
function bindDragEvents() {
|
||||
document.addEventListener('mousemove', handleDragMoving)
|
||||
document.addEventListener('touchmove', handleDragMoving, { passive: false })
|
||||
document.body.style.userSelect = 'none'
|
||||
document.body.style.cursor = 'grabbing'
|
||||
}
|
||||
|
||||
function unbindDragEvents() {
|
||||
document.removeEventListener('mousemove', handleDragMoving)
|
||||
document.removeEventListener('touchmove', handleDragMoving)
|
||||
document.body.style.userSelect = ''
|
||||
document.body.style.cursor = ''
|
||||
}
|
||||
|
||||
function getOffset() {
|
||||
@@ -64,15 +83,18 @@ function getOffset() {
|
||||
|
||||
function handleDragStart(e) {
|
||||
if (isPassing.value || props.disabled) return
|
||||
if (e.cancelable && e.type !== 'touchstart') e.preventDefault() // 阻止拖拽时选中文本
|
||||
moveStartX.value = getEventPageX(e)
|
||||
const currentLeft = Number.parseInt(actionLeft.value || '0', 10)
|
||||
moveDistance.value = moveStartX.value - currentLeft
|
||||
isMoving.value = true
|
||||
bindDragEvents()
|
||||
emit('start', e)
|
||||
}
|
||||
|
||||
function handleDragMoving(e) {
|
||||
if (!isMoving.value || isPassing.value) return
|
||||
if (e.cancelable) e.preventDefault() // 移动端阻止页面跟随滚动
|
||||
const action = actionRef.value
|
||||
const bar = barRef.value
|
||||
if (!action || !bar) return
|
||||
@@ -103,6 +125,7 @@ function onDocumentMouseUp(e) {
|
||||
|
||||
function handleDragEnd(e) {
|
||||
if (!isMoving.value || isPassing.value) return
|
||||
unbindDragEvents()
|
||||
emit('end', e)
|
||||
const action = actionRef.value
|
||||
const bar = barRef.value
|
||||
@@ -123,12 +146,14 @@ function handleDragEnd(e) {
|
||||
}
|
||||
|
||||
function checkPass() {
|
||||
unbindDragEvents()
|
||||
isPassing.value = true
|
||||
isMoving.value = false
|
||||
emit('update:modelValue', true)
|
||||
}
|
||||
|
||||
function resume() {
|
||||
unbindDragEvents()
|
||||
isMoving.value = false
|
||||
isPassing.value = false
|
||||
moveDistance.value = 0
|
||||
@@ -144,14 +169,23 @@ function resume() {
|
||||
})
|
||||
}
|
||||
|
||||
// 鼠标在窗口外松开 / 切换窗口时收不到 mouseup,兜底取消拖拽,避免一直跟随鼠标
|
||||
function onWindowBlur() {
|
||||
if (!isMoving.value) return
|
||||
resume()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('mouseup', onDocumentMouseUp)
|
||||
document.addEventListener('touchend', onDocumentMouseUp)
|
||||
window.addEventListener('blur', onWindowBlur)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
unbindDragEvents()
|
||||
document.removeEventListener('mouseup', onDocumentMouseUp)
|
||||
document.removeEventListener('touchend', onDocumentMouseUp)
|
||||
window.removeEventListener('blur', onWindowBlur)
|
||||
})
|
||||
|
||||
defineExpose({ resume })
|
||||
@@ -162,8 +196,6 @@ defineExpose({ resume })
|
||||
ref="wrapperRef"
|
||||
class="scaptcha"
|
||||
:class="{ 'scaptcha--disabled': disabled, 'scaptcha--passed': isPassing }"
|
||||
@mousemove="handleDragMoving"
|
||||
@touchmove="handleDragMoving"
|
||||
>
|
||||
<!-- 进度条 -->
|
||||
<div
|
||||
@@ -271,6 +303,7 @@ defineExpose({ resume })
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
|
||||
color: var(--fms-text-secondary);
|
||||
cursor: grab;
|
||||
touch-action: none; /* 移动端禁止手势接管滑动 */
|
||||
transition: box-shadow 150ms ease, color 200ms ease;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user