效果展示:
代码:
<template>
<div class="slider-box" ref="sliderBoxRef">
<div ref="sliderRef" id="slider" @pointerdown="pointerdown" @pointerup="pointerup">滑块</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const sliderRef = ref()
const sliderBoxRef = ref()
let shiftX = 0
const pointerdown = (e: PointerEvent) => {
shiftX = e.clientX - sliderRef.value.getBoundingClientRect().left
sliderRef.value.setPointerCapture(e.pointerId)
sliderRef.value.addEventListener('pointermove', sliderMove)
}
const pointerup = (e: PointerEvent) => {
sliderRef.value.removeEventListener('pointermove', sliderMove)
}
const sliderMove = (e: PointerEvent) => {
const { width: boxWidth, left: boxLeft } = sliderBoxRef.value.getBoundingClientRect()
const { width } = sliderRef.value.getBoundingClientRect()
let newLeft = e.clientX - shiftX - boxLeft
const rightEdge = boxWidth - width
if (newLeft < 0) {
newLeft = 0
}
if (newLeft > rightEdge) {
newLeft = rightEdge
}
sliderRef.value.style.transform = `translate(${newLeft}px)`
}
</script>
<style lang="scss" scoped>
.slider-box {
background-color: skyblue;
border-radius: 10px;
}
#slider {
width: 140px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
background-color: palevioletred;
cursor: move;
user-select: none;
border-radius: 10px;
}
</style>