当前位置: 首页 > news >正文

vue3项目移动端实现进度条可手动滑动控制进度和点击控制进度

最终效果
在这里插入图片描述
完整代码:

<template><div class="slider-container"><div class="slider-track" ref="trackRef"><div class="slider-thumb" ref="thumbRef"@touchstart="handleTouchStart"@touchmove="handleTouchMove"@touchend="handleTouchEnd":style="{ left: thumbPosition }"></div><div class="slider-progress" :style="{ width: progressWidth }"></div><div v-for="n in 10" :key="n" class="slider-mark":style="{ left: `${(n - 1) * 100 / 9}%` }"></div><!-- 添加单独的点击区域 --><div v-for="n in 10" :key="'click-' + n" class="slider-click-area":style="{ left: `${(n - 1) * 100 / 9}%` }"@click="jumpToValue(n)"@touchstart="jumpToValue(n)"></div><div v-for="n in 10" :key="'label-' + n" class="slider-label":style="{ left: `${(n - 1) * 100 / 9}%` }">{{ n }}</div></div><div class="slider-value">当前值: {{ currentValue }}</div></div></template><script lang="ts" setup>import { ref, computed } from 'vue'const trackRef = ref<HTMLDivElement | null>(null)const thumbRef = ref<HTMLDivElement | null>(null)const currentValue = ref(1)const isDragging = ref(false)const startX = ref(0)const thumbStartLeft = ref(0)const progressWidth = computed(() => {return `${(currentValue.value - 1) * 100 / 9}%`})const thumbPosition = computed(() => {return `${(currentValue.value - 1) * 100 / 9}%`})function handleTouchStart(e: TouchEvent) {isDragging.value = truestartX.value = e.touches[0].clientXconst thumbRect = thumbRef.value?.getBoundingClientRect()thumbStartLeft.value = thumbRect?.left || 0e.preventDefault()}function handleTouchMove(e: TouchEvent) {if (!isDragging.value) returnconst trackRect = trackRef.value?.getBoundingClientRect()const trackWidth = trackRect?.width || 0let moveX = e.touches[0].clientX - startX.valuelet newLeft = thumbStartLeft.value + moveX - (trackRect?.left || 0)// 限制在轨道范围内newLeft = Math.max(0, Math.min(newLeft, trackWidth))// 计算最接近的刻度位置const percent = newLeft / trackWidthconst closestValue = Math.round(percent * 9) + 1// 只有当移动距离足够大时才更新值,避免抖动if (Math.abs(percent - (currentValue.value - 1)/9) > 0.03) {currentValue.value = Math.max(1, Math.min(10, closestValue))}e.preventDefault()}function handleTouchEnd() {// 滑动结束时确保对准最近的刻度currentValue.value = Math.round(currentValue.value)isDragging.value = false}function jumpToValue(value: number) {currentValue.value = value;}</script><style scoped>.slider-container {/* padding: 20px; */width: 85%;max-width: 500px;margin: 0 auto;}.slider-track {position: relative;height: 4px;background-color: #e0e0e0;border-radius: 2px;margin: 30px 0 40px;}.slider-progress {position: absolute;height: 100%;background-color: #42b983;border-radius: 2px;pointer-events: none;}.slider-thumb {position: absolute;width: 24px;height: 24px;background-color: #42b983;border-radius: 50%;top: 50%;transform: translate(-50%, -50%);cursor: pointer;z-index: 4; /* 确保在最上层 */touch-action: none;}.slider-mark {position: absolute;width: 8px;height: 8px;background-color: #fff;border: 2px solid #e0e0e0;border-radius: 50%;top: 50%;transform: translate(-50%, -50%);pointer-events: none;z-index: 1;}.slider-label {position: absolute;top: 20px;transform: translateX(-50%);font-size: 12px;color: #666;pointer-events: none; /* 标签本身不接受事件 */z-index: 2;user-select: none;}/* 新增的点击区域 */.slider-click-area {position: absolute;width: 30px;height: 40px;top: -10px;transform: translateX(-50%);z-index: 3; /* 在标签和滑块之间 */cursor: pointer;}</style>

使用:

<NumberSlider />import NumberSlider from '@/components/m/numberSlider.vue';

相关文章:

  • 我的世界进阶模组开发教程——开发机械动力附属模组(2)
  • 使用Python和PyTorch框架,基于RetinaNet模型进行目标检测,包含数据准备、模型训练、评估指标计算和可视化
  • linux 安装 opencv源码4.5.4记录
  • DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_学习计划日历示例(CalendarView01_20)
  • Python图像处理基础(六)
  • (十三)计算机视觉中的深度学习:特征表示、模型架构与视觉认知原理
  • 第29节 Node.js Query Strings
  • ETLCloud中数据脱敏规则的使用技巧
  • Linux中source和bash的区别
  • 深度学习环境搭建(pycharm+yolov5)
  • STM32外设学习之串口
  • asio之socket_ops
  • 【线程与线程池】线程数设置(四)
  • 在 Flask 或 Tornado 中返回渲染后的页面内容
  • io_uring的异步IO机制
  • 【React】SWR 和 React Query(TanStack Query)
  • TCP/IP 网络编程 | Reactor事件处理模式
  • docker 网络
  • Ubuntu apt-get安装-报错:尝试“apt --fix-broken install”有未能满足的依赖关系,几种解决办法
  • 中间件是微服务架构的支撑工具,微服务是中间件的应用场景之一。
  • 怎么做卡盟网站免费/百度发广告需要多少钱
  • 做招聘网站需要哪些手续/真正免费的网站建站
  • 建设工程质量安全管理协会网站/app优化方案
  • 重庆网站建设安全/百度新版本更新下载
  • 网络公司网络推广服务/seo外包优化网站
  • 十堰响应式网站/如何做网络宣传推广