jQuery实现的range滑块PC端正常但触屏设备失效如何修复
jQuery范围滑块触屏设备失效修复方案
问题说明
使用jQuery编写的双范围滑块在PC端运行正常,触屏设备拖动滑块无响应,已尝试的touch相关事件绑定方案均无效。
已尝试的无效方案
- 使用
on('touchmove', rangeInputChangeEventHandler);替换on('input', rangeInputChangeEventHandler);,未生效 - 在input事件绑定后新增
$('input[type="range"]').on( 'touchstart', rangeInputChangeEventHandler);,未解决问题
核心问题排查
- 事件绑定兼容不足:仅绑定
input事件,部分移动端浏览器拖动range滑块时不会持续触发input事件,需要额外兼容change、touchmove、touchend事件 - 事件目标取值错误:代码中使用
e.originalEvent.target.className判断当前操作的滑块,触屏场景下事件冒泡会导致target指向错误元素,origin判断失效导致互锁逻辑和数值更新逻辑不运行 - 触屏行为冲突:未声明滑块的触摸行为规则,容易和页面默认的上下滚动行为冲突,导致滑块拖动被拦截
修复步骤
1. 修改事件绑定逻辑
找到JS代码中最后的事件绑定行,替换为多事件兼容绑定:
// 原代码:$('input[type="range"]').on('input', rangeInputChangeEventHandler); // 替换为以下代码 $('input[type="range"]').on('input change touchmove touchend', rangeInputChangeEventHandler);
2. 修正滑块标识取值逻辑
找到rangeInputChangeEventHandler函数中origin变量的定义行,替换为直接取当前触发事件的元素类名:
// 原代码:origin = e.originalEvent.target.className; // 替换为以下代码 origin = this.className;
3. 新增CSS触屏行为规则
在CSS的input[type='range']选择器中新增touch-action属性,避免和页面滚动冲突:
input[type='range'] { /* 原有属性保留,新增以下一行 */ touch-action: pan-y; width: 210px; height: 30px; padding: 20px; overflow: hidden; cursor: pointer; outline: none; }
完整修改后的代码
JavaScript
//main function change number of slider when dragging (function() { // function to round up number function lamtronTien(number) { // set rounded, currentForamt, tienFormat as varibale var rounded = Math.round(number / 1000000) * 1000000; var currentFormat = new Intl.NumberFormat("vn-VN"); var tienFormat = currentFormat.format(rounded); // return tienFormat; } //function to turn number into word function docSoTien(number) { // replace "," with "" number = number.replaceAll(",", ""); // set variable ty and trieu as below var ty = Math.pow(10, 9); var trieu = Math.pow(10, 6); // when number = 0 return 0 if (number === "0") { return 0; // else number is larger than ty } else { if (number >= ty) { // set variable as floor of "number" devided by "ty" var hangTy = Math.floor(number / ty); // if hangTy is greater than 1 then result if (hangTy >= 1) { // set varibales var hangTrieu = number % ty; var hangTrieu = Math.floor(hangTrieu / trieu); if (hangTrieu > 0) { return (hangTy + " Tỷ " + hangTrieu + " Triệu"); // else } else { return (hangTy + " Tỷ"); } } } else { // var hangTrieu = number % ty; var hangTrieu = Math.floor(number / trieu); if (hangTrieu > 0) { return (hangTrieu + " Triệu"); } } } } // function to apply change when there is a change in number input function rangeInputChangeEventHandler(e) { // set attribute name as rangeGroup var rangeGroup = $(this).attr('name'), minBtn = $(this).parent().children('.min'), maxBtn = $(this).parent().children('.max'), // get value of range_min, range_max range_min = $(this).parent().children('.range_min'), range_max = $(this).parent().children('.range_max'), minVal = parseInt($(minBtn).val()), maxVal = parseInt($(maxBtn).val()), // 修改取值逻辑 origin = this.className; // if origin if (origin === 'min' && minVal > maxVal - 5) { $(minBtn).val(maxVal - 5); } var minVal = parseInt($(minBtn).val()); $(range_min).html(docSoTien(lamtronTien(minVal))); // if origin is max and maxVal minus 5 is smaller than minVal if (origin === 'max' && maxVal - 5 < minVal) { $(maxBtn).val(5 + minVal); } var maxVal = parseInt($(maxBtn).val()); if (docSoTien(lamtronTien(maxVal)) === '3 Tỷ') { $(range_max).html('> 3 Tỷ'); } else { // apply to range_max $(range_max).html(docSoTien(lamtronTien(maxVal))); }; } // 绑定多兼容事件 $('input[type="range"]').on('input change touchmove touchend', rangeInputChangeEventHandler); })();
CSS
/* adjust */ input[type='range'] { touch-action: pan-y; width: 210px; height: 30px; padding: 20px; overflow: hidden; cursor: pointer; outline: none; } /* adjust */ input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb { -webkit-appearance: none; background: none; } /* adjust */ input[type='range']::-webkit-slider-runnable-track { width: 300px; height: 1px; background: #003D7C; } /* adjust */ input[type='range']:nth-child(2)::-webkit-slider-runnable-track { background: none; } /* adjust */ input[type='range']::-webkit-slider-thumb { position: relative; height: 15px; width: 15px; margin-top: -7px; background: #fff; border: 1px solid #003D7C; border-radius: 25px; z-index: 1; } /* adjust */ input[type='range']:nth-child(1)::-webkit-slider-thumb { z-index: 2; } .rangeslider { height: 60px; width: 210px; display: inline-block; margin-top: -5px; margin-left: 20px; } /* adjust rangeslider input */ .rangeslider input { position: absolute; } /* adjust rangeslider */ .rangeslider { position: absolute; } /* adjust rangeslider span*/ .rangeslider span { margin-top: 30px; left: 0; } /* adjust rangeslider right thumb */ .rangeslider .right { position: relative; float: right; margin-right: -70px; margin-top: -3px; }
HTML
<!-- slider --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!-- slider --> <div class="slider-group"> <div class="rangeslider"> <input class="min" name="min" type="range" min="0" max="3000000000" value="0" /> <input class="max" name="max" type="range" min="0" max="3000000000" value="3000000000" /> <span class="range_min light left">0</span> <span class="range_max light right"> > 3 Tỷ</span> </div> </div>
内容的提问来源于stack exchange,提问作者nguyen nam
相关产品推荐
相关产品推荐

