本文详解如何通过 jquery 实现“仅当所有数字输入框(1–20、两位数)全部验证通过后,点击搜索按钮才关闭全屏搜索弹窗”,修复原代码中因逐个判断导致的逻辑错误,并优化验证结构与用户体验。
在构建全屏搜索覆盖层(overlay)时,一个常见但易被忽视的关键交互逻辑是:关闭动作不应依赖单个输入的状态,而应基于整体表单的有效性。原始代码中,.send_btn 的 click 事件对每个 .each_item 输入单独执行 handleChange() 并立即应用样式与 DOM 操作(如 addClass('open')),导致后续输入的处理覆盖了前序结果——最终行为仅由最后一个输入决定,违背了“全部有效才关闭”的设计目标。
核心改进在于分离验证逻辑与副作用操作:
以下是精简、健壮的实现代码:
$(function() {
// 打开搜索弹窗
$('a[href="#search"]').on("click", function(event) {
event.preventDefault();
$("#search").addClass("open");
$('#search .search__input:first').focus(); // 聚焦首个输入框
});
// 点击遮罩或关闭按钮(含 ESC 键)关闭弹窗
$("#search, #search .close").on("click keyup", function(event) {
if (
event.target === this ||
$(event.target).hasClass("close") ||
event.keyCode === 27 // ESC
) {
$("#search").removeClass("open");
$("html").removeClass("noScrollSimple");
}
});
// 阻止表单默认提交
$(".send_btn").on("click", function(event) {
event.preventDefault();
});
});
// 单输入校验函数:返回布尔值,明确标识有效性
function handleChange(input) {
const value = input.value.trim();
// 清空非法前置零或负号
if (value === "" || value === "0" || value.startsWith("00")) {
input.value = "";
input.style.borderColor = "red";
return false;
}
const num = Number(value);
// 规则:必须为 1–20 的整数,且长度为 1 或 2 位(允许 "1"~"9" 和 "10"~"20")
if (isNaN(num) || num < 1 || num > 20 || !Number.isInteger(num)) {
input.style.borderColor = "red";
return false;
}
input.style.borderColor = "";
return true;
}
// 搜索按钮点击:批量验证,统一控制弹窗状态
$('.send_btn').on('click', function() {
const inputs = $('.search__input');
const results = [];
inputs.each(function() {
results.push(handleChange(this));
});
// ✅ 关键逻辑:仅当所有输入均有效时关闭弹窗
if (!results.includes(false)) {
$("#search").removeClass("open");
$("html").removeClass("noScrollSimple");
} else {
// 至少一个输入无效:确保弹窗保持开启,并阻止页面滚动(可选增强体验)
$("#search").addClass("open");
$("html").addClass("noScrollSimple");
}
});
通过以上重构,搜索弹窗的关闭逻辑变得清晰、可靠且符合用户预期:不是“任意一个好了就关”,而是“全部达标才放行”——这是表单驱动交互设计的基本原则,也是专业前端实现的重要体现。