input新类型type="range"的使用,针对样式的改写

本文介绍如何通过CSS和JavaScript自定义HTML中range输入类型的样式,实现动态改变背景比例和拖动块样式,同时更新相关数值显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近公司的一些项目需要,对input的新类型range进行了一番的使用,主要是针对它的样式进行了重新的改写。达到下面的这种需求,我移动range上面的小球,它会随着我的移动而改变它的值,如图:

   开始的位置移动过程中

可能网上也有很多这样的例子,但是我还是把我的分享一下,代码简单的很,只需要选择节点就可以了。代码如下:

css部分:

input[type=range]{ 
         margin-top: 8px;
             outline: none; 
         -webkit-appearance: none;/*清除系统默认样式*/  
         width:56% !important;  
         background: -webkit-linear-gradient(#61bd12, #61bd12) no-repeat, #ddd;  
             background-size: 30% 100%;/*设置左右宽度比例*/  
        height: 3px;/*横条的高度*/  

 /*拖动块的样式*/  
   input[type=range]::-webkit-slider-thumb {  
     -webkit-appearance: none;/*清除系统默认样式*/  
    height:16px;/*拖动块高度*/  
        width: 16px;/*拖动块宽度*/  
        background: #fff;/*拖动块背景*/  
    border-radius: 50%; /*外观设置为圆形*/  
     border: solid 1px #ddd; /*设置边框*/  

HTML部分:
<div class="an_speed after_clear">
   <span>速度:</span>
   <input type="range" name="range_speed" id="range_speed" value="30" oninput="changeSpeed()" />
   <span id="value1">3.0</span>秒
</div>
JavaScript部分:这里我引入了jQuery,大家可以自己去网上找一份引入。

<script type="text/javascript">
    
    function changeSpeed() {
        var value = $('#range_speed').val();
        var valStr = value + "% 100%";
        $('#value1').html((value / 10).toFixed(1));
        $('#range_speed').css({
          "background-size": valStr
        })
        $("input[name='animat_speed']").val((value / 10).toFixed(1));
    };
</script>

这样就可以达到我上面的效果,供大家参考.....

--------------------- 
原文:https://blog.youkuaiyun.com/zhanghuiqi205/article/details/74989743 

<template> <div class="scale-component"> <div ref="container" class="scale-container" @click="handleClick" > <!-- 刻度线 --> 修改为适应vue2的代码 <div v-for="tick in visibleTicks" :key="tick.value" class="tick" :class="tick.class" :style="{ left: tick.position + '%' }" > <!-- 标签渲染 --> <span v-if="tick.showLabel" class="tick-label" :style="getLabelStyle(tick)" > {{ tick.label }} </span> </div> <!-- 指示器 --> <div class="indicator" :style="{ left: currentPosition + '%' }" > <div class="pointer"></div> <span class="indicator-value">{{ currentValue.toFixed(1) }}</span> </div> </div> </div> </template> <script> import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'; export default { props: { min: { type: Number, default: 0 }, max: { type: Number, default: 10.0 }, step: { type: Number, default: 0.1 }, modelValue: { type: Number, default: 0 }, showHalfLabels: { type: Boolean, default: true }, densityThreshold: { type: Number, default: 30 } // 最小像素间距 }, emits: ['update:modelValue'], setup(props, { emit }) { const container = ref(null); const containerWidth = ref(0); const currentValue = ref(props.modelValue); // 监听容器宽度变化 const observer = new ResizeObserver(entries => { if (entries[0]) containerWidth.value = entries[0].contentRect.width; }); // 生成所有刻度点 (101个) const allTicks = computed(() => { const ticks = []; const range = props.max - props.min; for (let value = props.min; value <= props.max; value += props.step) { const position = ((value - props.min) / range) * 100; const isMajor = value % 1 === 0; const isMinor = !isMajor && value % 0.5 === 0; const isEdge = value === props.min || value === props.max; ticks.push({ value, position, class: { 'major-tick': isMajor, 'minor-tick': isMinor, 'micro-tick': !isMajor && !isMinor, 'edge-tick': isEdge }, label: isMajor ? value.toFixed(0) : value.toFixed(1), showLabel: false // 初始不显示 }); } return ticks; }); // 智能渲染可见刻度 const visibleTicks = computed(() => { if (!containerWidth.value) return []; const minSpacing = props.densityThreshold; // 最小间距(像素) const visible = []; let lastLabelPos = -minSpacing; // 最后标签位置 for (const tick of allTicks.value) { const pixelPos = (tick.position / 100) * containerWidth.value; const isMajor = tick.value % 1 === 0; const isMinor = !isMajor && tick.value % 0.5 === 0; const isEdge = tick.value === props.min || tick.value === props.max; // 智能显示标签 tick.showLabel = false; // 边缘标签始终显示 if (isEdge) { tick.showLabel = true; lastLabelPos = pixelPos; } // 整数标签智能显示 else if (isMajor) { if (pixelPos - lastLabelPos >= minSpacing) { tick.showLabel = true; lastLabelPos = pixelPos; } } // 0.5标签智能显示 else if (isMinor && props.showHalfLabels) { if (pixelPos - lastLabelPos >= minSpacing * 0.7) { tick.showLabel = true; lastLabelPos = pixelPos; } } // 微刻度根据密度显示 const shouldRender = isMajor || isMinor || (containerWidth.value / allTicks.value.length > 5) || isEdge; if (shouldRender) visible.push(tick); } return visible; }); // 当前值位置 const currentPosition = computed(() => { return ((currentValue.value - props.min) / (props.max - props.min)) * 100; }); // 标签防溢出样式 const getLabelStyle = (tick) => { const isMin = tick.value === props.min; const isMax = tick.value === props.max; if (isMin) { return { transform: 'translateX(0)', left: '0.5em' }; } else if (isMax) { return { transform: 'translateX(-100%)', left: 'auto', right: '0.5em' }; } else { return { transform: 'translateX(-50%)' }; } }; // 点击设置值 const handleClick = (event) => { if (!container.value) return; const rect = container.value.getBoundingClientRect(); const offsetX = event.clientX - rect.left; const percent = offsetX / rect.width; // 计算值 const newValue = props.min + percent * (props.max - props.min); // 步长取整 const steps = Math.round((newValue - props.min) / props.step); const fixedValue = Math.min(props.max, Math.max(props.min, props.min + steps * props.step)); currentValue.value = fixedValue; emit('update:modelValue', fixedValue); }; // 响应式监听 onMounted(() => { if (container.value) observer.observe(container.value); }); onBeforeUnmount(() => { if (container.value) observer.unobserve(container.value); }); // 监听外部值变化 watch(() => props.modelValue, (newVal) => { currentValue.value = newVal; }); return { container, visibleTicks, currentPosition, currentValue, getLabelStyle, handleClick }; } }; </script>
最新发布
08-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值