如何解决document.querySelectorAll获取jQuery Datepicker控件返回空的问题
首先,咱们先定位你代码里最核心的问题:选择器写法错误。你写的datepickerFilterStartDate和datepickerFilterEndDate如果是元素的ID(从你的controlList和后续代码里的#datepickerInputStart来看,应该是ID),那在CSS选择器里必须加#前缀——不然querySelectorAll会把它们当成HTML标签名,而根本不存在叫<datepickerFilterStartDate>的标签,所以返回空结果是必然的。
正确的选择器写法
把你的选择器改成这样,就能正确获取到目标元素了:
allInputsAndSelects = document.querySelectorAll('input, select, #datepickerFilterStartDate, #datepickerFilterEndDate');
不过这里还要补充一点:jQuery Datepicker初始化后,有时候会把原始的<input>元素隐藏,生成一个带样式的容器和新的输入区域。如果你的目标是Datepicker绑定的原始input,最好直接通过它的ID来获取,或者确保选择器指向的是实际可见/存在的input元素。
额外的代码优化建议
除了选择器的问题,你的代码里还有几个可以改进的地方,能让逻辑更健壮:
1. 操作类名不要用字符串加减
你现在用className - " inprogress"这种写法完全错误,字符串不能用减法操作。应该用原生的classListAPI,更简洁可靠:
// 替换这种错误写法: // document.getElementById("datepickerInputStart").className = document.getElementById("datepickerInputStart").className - " inprogress"; // 改成: const inputEl = document.getElementById("datepickerInputStart"); inputEl.classList.remove("inprogress"); inputEl.classList.remove("required"); inputEl.classList.add("successful");
这样不仅代码更清晰,还不会出现类名拼接错误的问题。
2. 简化checkControlExistence函数
你当前的函数逻辑有点绕,可以简化成更高效的版本:
function checkControlExistence(controlsToCheckFor) { // 生成包含所有待检查控件名的属性选择器 const selectors = controlsToCheckFor.map(id => `[name*="${id}"]`).join(','); const foundElements = document.querySelectorAll(`input, select, ${selectors}`); // 验证每个待检查控件是否都能匹配到元素 return controlsToCheckFor.every(control => { return Array.from(foundElements).some(el => el.name.includes(control)); }); }
这样逻辑更清晰,也减少了嵌套循环的复杂度。
3. 避免重复获取DOM元素
你的代码里多次调用$("#datepickerInputStart").val()和document.getElementById("datepickerInputStart"),可以把元素缓存起来,提升性能:
const datepickerInput = $("#datepickerInputStart"); const valToCheck = datepickerInput.val(); // 后续直接用datepickerInput操作即可
最后再确认一下:如果你的Datepicker是通过jQuery初始化的,比如$("#datepickerInputStart").datepicker(),那原始input元素的ID是不变的,直接用#datepickerInputStart就能获取到,不需要额外的特殊选择器。
内容的提问来源于stack exchange,提问作者Bbb

