使用同一类名的jQuery UI Range Slider初始化数据值不显示问题
解决多个jQuery UI Range Slider初始化时第二个滑块不显示数据值的问题
问题根源
你遇到的问题出在create事件的回调逻辑里:当初始化第二个滑块时,页面上已经存在第一个滑块的两个.ui-slider-handle元素了,这时候你用全局选择器$('.ui-slider-handle').eq(i)去获取手柄,会选中第一个滑块的手柄,而不是当前正在初始化的第二个滑块的手柄,导致第二个滑块的手柄没有被设置初始的data-value,只有拖动时(slide事件)才会触发updateValue去设置值。
修复方案
我们需要在create事件中,基于当前正在初始化的滑块来查找它自己的手柄,而不是全局查找所有手柄。同时,为了让每个滑块可以独立控制初始值(就算现在用相同值,这样的写法也更健壮),我们可以把初始值的逻辑和当前滑块绑定。
修改后的完整代码
HTML部分
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script> <div class="time-range"> <div class="sliders_step1"> <div class="slider-range"></div> </div> </div> <div class="time-range"> <div class="sliders_step1"> <div class="slider-range"></div> </div> </div>
CSS部分
.time-range { padding-top: 35px; } *:focus { outline: 0; } .ui-slider-horizontal { height: 8px; background: #D7D7D7; border: 1px solid #BABABA; box-shadow: 0 1px 0 #FFF, 0 1px 0 #CFCFCF inset; clear: both; margin: 8px 0; -webkit-border-radius: 6px; -moz-border-radius: 6px; -ms-border-radius: 6px; -o-border-radius: 6px; border-radius: 6px; } .ui-slider { position: relative; text-align: left; } .ui-slider-horizontal .ui-slider-range { top: -1px; height: 100%; } .ui-slider .ui-slider-range { position: absolute; z-index: 1; height: 8px; font-size: .7em; display: block; border: 1px solid #424453; box-shadow: 0 1px 0 #edeef7 inset; -moz-border-radius: 6px; -webkit-border-radius: 6px; -khtml-border-radius: 6px; border-radius: 6px; } .ui-slider .ui-slider-handle { background-color: #424453; width: 18px; height: 18px; } .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 18px; height: 18px; cursor: default; border: none; cursor: pointer; background: transparent url(https://dummyimage.com/4x20/000/fff.png) 50% 50% no-repeat; } .ui-slider-horizontal .ui-slider-handle { top: -.5em; margin-left: -.7em; } .ui-slider-handle:after { content: attr(data-value); position: absolute; bottom: -24px; left: -20px; min-width: 60px; font-size: 10px; height: 20px; color: #333; padding: 1px; text-align: center; } .ui-slider a:focus { outline: none; } #slider-range { width: 95%; margin: 0px; } .time-range { width: 100%; margin: 10px 0px; display: block; } .time-slider-label { display: inline-block; } .sliders_step1 { width: auto; } #time-range label { margin-top: 10px; }
JavaScript部分
$(document).ready(function() { // 可以给每个滑块设置独立的初始值,这里暂时用相同值示例 const sliderConfigs = [ { values: [540, 1020] }, { values: [540, 1020] } ]; const updateValue = function(ui) { var hours = Math.floor(ui.value / 60); var minutes = ui.value - (hours * 60); // 补零逻辑优化(原逻辑中hours是数字,没有length属性,这里修正) hours = hours.toString().padStart(2, '0'); minutes = minutes.toString().padStart(2, '0'); var period = "AM"; if (hours >= 12) { period = "PM"; if (hours > 12) { hours = (hours - 12).toString().padStart(2, '0'); } } if (hours === "00") { hours = "12"; } $(ui.handle).attr('data-value', `${hours}:${minutes} ${period}`); }; $(" .slider-range").each(function(index) { const config = sliderConfigs[index]; $(this).slider({ min: 0, max: 1440, step: 15, range: true, values: config.values, create: function(event, ui) { // 关键:获取当前滑块自己的手柄,而不是全局所有手柄 const $handles = $(this).find('.ui-slider-handle'); $.each(config.values, function(i, v) { updateValue({ value: v, handle: $handles.eq(i) }); }); }, slide: function(event, ui) { updateValue(ui); } }); }); });
额外优化说明
- 修复了原代码中
hours.length == 1的错误:hours是数字类型,没有length属性,改用padStart方法来补零,逻辑更简洁可靠。 - 用
each方法遍历每个滑块,给每个滑块绑定独立的配置,后续如果需要不同的初始值,直接修改sliderConfigs数组即可。 - 在
create事件中通过$(this).find('.ui-slider-handle')获取当前滑块的手柄,确保每个滑块只操作自己的元素。
现在运行修改后的代码,两个滑块初始化时都会正确显示初始的时间值,不需要拖动就能看到效果。
内容的提问来源于stack exchange,提问作者Hiren Vaghasiya
相关产品推荐
相关产品推荐

