效果展示:
参数说明:
adsorbLen
:为0则不吸附,不为0则为左右吸附的距离。也可以自己修改左右的吸附长度。
代码:
<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()
const adsorbLen = 0 // 吸附效果,吸附长度,为0不吸附const pointerdown = (e: PointerEvent) => {document.addEventListener('pointermove', sliderMove)sliderRef.value.setPointerCapture(e.pointerId) // 用于将特定元素指定为未来指针事件的捕获目标。
}
const pointerup = (e: PointerEvent) => {document.removeEventListener('pointermove', sliderMove)sliderRef.value.releasePointerCapture(e.pointerId) // 用来将鼠标指针从先前通过 setPointerCapture() 绑定的元素身上释放出来,还给鼠标指针自由。
}
const sliderMove = (e: PointerEvent) => {const { right: boxRight } = sliderBoxRef.value.getBoundingClientRect()// 滑块距起点位置const startX = e.clientX - 290 // 220(220是容器距离左边视口区的位置)+70(元素宽度的一半,让鼠标处于中心)// 滑块终点const endX = boxRight - 360 // 220+140(140是滑块的宽度)// 滑块移动距离const transformX = startX < adsorbLen ? 0 : (endX - startX < adsorbLen ? endX : startX)if (transformX >= 0) {sliderRef.value.style.transform = `translate(${transformX}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>