如何阻止页面touchmove同时保留时间选择器滚动功能
问题:页面固定后时间选择器无法滚动
问题场景
为固定页面,给document绑定touchmove事件并阻止默认行为,导致时间选择器(timepicker)下拉选项无法滚动:
function preventBehavior(e) { e.preventDefault(); }; document.addEventListener("touchmove", preventBehavior, {passive: false});
尝试给timepicker元素添加touchmove事件并阻止事件传播,未生效:
function allowBehavior(e){ e.stopPropagation() } let tp = document.getElementsByClassName('timepicker') for(let i = 0; i < tp.length; i++){ tp[i].addEventListener("touchmove", allowBehavior, {passive: false}); }
原因分析
- 时间选择器的滚动区域并非页面上的
input.timepicker元素,而是插件动态生成的独立下拉容器,之前绑定事件到input上完全无效。 stopPropagation()仅阻止事件向上冒泡,但document的touchmove事件监听在最顶层,事件最终仍会到达document,无法绕过全局的preventDefault()。
解决方案
方案一:在全局touchmove事件中判断目标元素
修改全局的preventBehavior函数,检查事件触发目标是否属于时间选择器的滚动容器,若是则不阻止默认行为:
function preventBehavior(e) { let target = e.target; // 遍历目标元素的父节点,判断是否在timepicker滚动容器内 while (target) { // 替换为你实际使用的timepicker下拉容器类名(打开时间选择器后查看网页源码获取) if (target.classList.contains('ui-timepicker-wrapper')) { return; // 允许滚动,不阻止默认行为 } target = target.parentNode; } e.preventDefault(); // 其他情况阻止页面滚动 }; document.addEventListener("touchmove", preventBehavior, {passive: false});
注意:需打开时间选择器,通过浏览器开发者工具查看下拉容器的类名,替换代码中的
ui-timepicker-wrapper(不同版本的timepicker类名可能不同)。
方案二:监听timepicker弹出事件,给滚动容器绑定事件
利用timepicker插件的弹出事件,找到滚动容器并阻止事件冒泡到document:
// 当timepicker弹出时触发 $(document).on('timepickeropen', function() { const timepickerWrapper = document.querySelector('.ui-timepicker-wrapper'); if (timepickerWrapper) { // 给滚动容器绑定touchmove事件,阻止事件冒泡 timepickerWrapper.addEventListener('touchmove', function(e) { e.stopPropagation(); }, {passive: true}); } });
此方案依赖jquery timepicker的
timepickeropen事件,若插件版本不同,事件名称可能有变化,请参考插件文档调整。
两种方案任选其一,即可实现页面固定的同时让时间选择器选项正常滚动。
内容的提问来源于stack exchange,提问作者DCR
相关产品推荐
相关产品推荐

