
在现代 Web 应用中,表单验证是不可或缺的一环。良好的客户端验证不仅能提升用户体验,减少无效提交,还能减轻服务器端压力。HTML5 引入了原生的表单验证机制,如 required、type="email" 等属性,极大地简化了常见验证任务。然而,对于某些复杂的业务规则,例如信用卡号的 Luhn 算法验证,原生 HTML5 验证能力有限,需要结合 JavaScript 进行自定义扩展。
Luhn 算法(也称为模 10 算法)是一种简单的校验和算法,常用于验证各种识别号码,包括信用卡号。其核心思想是通过对数字序列进行特定计算,判断其是否符合规则。
以下是 Luhn 算法的 JavaScript 实现:
/**
* 校验给定的字符串是否符合 Luhn 算法规则
* @param {string} value 待校验的数字字符串
* @returns {boolean} 如果符合 Luhn 算法则返回 true,否则返回 false
*/
function checkLuhn(value) {
// 接受只包含数字、破折号或空格的字符串
if (/[^0-9-\s]+/.test(value)) return false;
let nCheck = 0,
nDigit = 0,
bEven = false;
// 移除所有非数字字符
value = value.replace(/\D/g, "");
// 从右向左遍历数字
for (let n = value.length - 1; n >= 0; n--) {
const cDigit = value.charAt(n);
nDigit = parseInt(cDigit, 10);
if (bEven) {
// 偶数位(从右边开始数的第二位、第四位...)数字乘以2
if ((nDigit *= 2) > 9) nDigit -= 9; // 如果结果大于9,则减去9
}
nCheck += nDigit; // 累加所有数字
bEven = !bEven; // 切换奇偶标志
}
// 如果总和能被10整除,则校验通过
return (nCheck % 10) === 0;
}Luhn 算法步骤解析:
HTML5 表单元素提供了一个 setCustomValidity() 方法,允许开发者设置自定义验证消息。当传入一个非空字符串时,该字段将被标记为无效,并显示该字符串作为验证消息;传入空字符串则表示字段有效。这是将自定义验证逻辑与浏览器原生验证机制无缝结合的关键。
以下是将 Luhn 算法集成到信用卡号输入字段的示例:
// 当信用卡号输入框内容变化时触发验证
$('#cc').on('input', function(){
// 获取信用卡号输入框的 DOM 元素
// 注意:这里需要确保 field 变量正确引用到输入框,
// 否则 setCustomValidity 将无法调用
const field = document.querySelector('#cardContainer input'); // 假设输入框在一个 id 为 'cardContainer' 的父元素内
if (checkLuhn($('#cc').val())) {
field.setCustomValidity(""); // 验证通过,清除自定义错误消息
} else {
field.setCustomValidity("Invalid field."); // 验证失败,设置自定义错误消息
}
});关键点说明:
除了自定义 Luhn 算法验证,一个完整的表单通常还包含其他字段(如姓名、邮箱)的原生 HTML5 验证。以下是结合所有验证逻辑的表单提交处理流程:
(function () {
"use strict";
const forms = document.querySelectorAll(".needs-validation");
const result = document.getElementById("result");
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener(
"submit",
function (event) {
// 在提交前,先执行所有验证(包括原生HTML5验证和通过setCustomValidity设置的自定义验证)
if (!form.checkValidity()) {
event.preventDefault(); // 阻止默认提交行为
event.stopPropagation(); // 阻止事件冒泡
// 聚焦到第一个无效字段
form.querySelectorAll(":invalid")[0].focus();
} else {
// 如果所有字段都有效,则处理表单提交(例如通过 Fetch API 发送到后端)
const formData = new FormData(form);
event.preventDefault();
event.stopPropagation();
const object = {};
formData.forEach((value, key) => {
object[key] = value;
});
const json = JSON.stringify(object);
result.innerHTML = "Please wait...";
fetch("https://api.web3forms.com/submit", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json"
},
body: json
})
.then(async (response) => {
let json = await response.json();
if (response.status === 200) {
result.innerHTML = json.message;
result.classList.remove("text-gray-500");
result.classList.add("text-green-500");
} else {
console.log(response);
result.innerHTML = json.message;
result.classList.remove("text-gray-500");
result.classList.add("text-red-500");
}
})
.catch((error) => {
console.log(error);
result.innerHTML = "Something went wrong!";
})
.then(function () {
form.reset(); // 重置表单
form.classList.remove("was-validated"); // 移除验证样式
setTimeout(() => {
result.style.display = "none";
}, 5000);
});
}
form.classList.add("was-validated"); // 添加验证样式,触发CSS显示错误信息
},
false
);
});
})();此流程的关键点:
为了支持上述验证逻辑和错误消息显示,HTML 结构需要包含相应的输入字段、标签和反馈消息占位符。同时,CSS 样式用于控制错误消息的显示和输入框的视觉反馈。
HTML 结构示例(信用卡号部分):
<div class="flex mb-6 space-x-4">
<div id="cardContainer" class="w-full md:w-1/2">
<label for="cc" class="block mb-2 text-sm text-gray-600 dark:text-gray-400">Credit Card Number</label>
<input type="text" id="cc" placeholder="XXXX XXXX XXXX XXXX" required
class="w-full px-3 py-2 placeholder-gray-300 border-2 border-gray-200 rounded-md focus:outline-none focus:ring focus:ring-indigo-100 focus:border-indigo-300" />
<!-- 提示用户输入为空的反馈信息 -->
<div class="empty-feedback text-red-400 text-sm mt-1">
Please provide your credit card number.
</div>
<!-- 提示用户输入无效的反馈信息 -->
<div class="invalid-feedback text-red-400 text-sm mt-1">
Please provide a valid credit card number.
</div>
</div>
</div>CSS 样式示例:
.invalid-feedback,
.empty-feedback {
display: none; /* 默认隐藏错误反馈 */
}
/* 当表单被标记为 'was-validated' 且输入框为空且无效时,显示 'empty-feedback' */
.was-validated :placeholder-shown:invalid ~ .empty-feedback {
display: block;
}
/* 当表单被标记为 'was-validated' 且输入框非空但无效时,显示 'invalid-feedback' */
.was-validated :not(:placeholder-shown):invalid ~ .invalid-feedback {
display: block;
}
/* 当输入框无效时,设置边框颜色 */
.is-invalid,
.was-validated :invalid {
border-color: #dc3545; /* 红色边框 */
}这些 CSS 规则利用了 :invalid、:placeholder-shown 等伪类和 ~ (兄弟选择器),配合 was-validated 类,实现了在不同验证状态下显示不同的错误消息和输入框样式。
通过本文的教程,您应该已经掌握了如何在前端表单中有效地集成自定义验证逻辑。利用 HTML5 的原生验证能力与 JavaScript 的 setCustomValidity() 方法,我们可以为用户提供一个既强大又用户友好的表单验证体验。无论是简单的必填项检查,还是复杂的 Luhn 算法校验,这种结合方式都能帮助您构建出更加健壮和可靠的 Web 表单。请记住,客户端验证是用户体验的基石,而服务器端验证则是数据安全的最后防线,两者缺一不可。
以上就是使用 Luhn 算法实现表单信用卡号验证的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号