有时,例如使用旧版浏览器或自定义小部件,您将无法(或不希望)使用约束校验API。 在这种情况下,您仍然可以使用 JavaScript 来校验您的表单。 校验表单比起真实数据校验更像是一个用户界面问题。
要校验表单,您必须问自己几个问题:
我应该进行什么样的校验?
你需要确定如何校验你的数据:字符串操作,类型转换,正则表达式等。这取决于你。 只要记住,表单数据一般都是文本,并总是以字符串形式提供给脚本。
如果表单校验失败,我该怎么办?
这显然是一个 UI 问题。 您必须决定表单的行为方式:表单是否发送数据? 是否突出显示错误的字段?是否显示错误消息?
如何帮助用户纠正无效数据?
不使用约束校验API 的例子
为了说明这一点,让我们重构一下前面的例子,以便它可以在旧版浏览器中使用:
Please enter an email address:
Submit
正如你所看到的,HTML 几乎是一样的;我们只是关闭了 HTML 校验功能。 请注意,ARIA 是与 HTML5 无关的独立规范。
CSS
同样的,CSS也不需要太多的改动, 我们只需将 :invalid 伪类变成真实的类,并避免使用不适用于 Internet Explorer 6 的属性选择器。
/* 仅为了使示例更好看 */
body {
font: 1em sans-serif;
padding: 0;
margin : 0;
}
form {
max-width: 200px;
}
p * {
display: block;
}
input.mail {
-webkit-appearance: none;
width: 100%;
border: 1px solid #333;
margin: 0;
font-family: inherit;
font-size: 90%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* 校验失败的元素样式 */
input.invalid{
border-color: #900;
background-color: #FDD;
}
input:focus.invalid {
outline: none;
}
/* 错误消息的样式 */
.error {
width : 100%;
padding: 0;
font-size: 80%;
color: white;
background-color: #900;
border-radius: 0 0 5px 5px;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.error.active {
padding: 0.3em;
}
JavaScript
JavaScript 代码有很大的变化,需要做更多的工作。
// 使用旧版浏览器选择 DOM 节点的方法较少
var form = document.getElementsByTagName('form')[0];
var email = document.getElementById('mail');
// 以下是在 DOM 中访问下一个兄弟元素的技巧
// 这比较危险,很容易引起无限循环
// 在现代浏览器中,应该使用 element.nextElementSibling
var error = email;
while ((error = error.nextSibling).nodeType != 1);
// 按照 HTML5 规范
var emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
// 许多旧版浏览器不支持 addEventListener 方法
// 这只是其中一种简单的处理方法
function addEvent(element, event, callback) {
var previousEventCallBack = element["on"+event];
element["on"+event] = function (e) {
var output = callback(e);
// 返回 `false` 来停止回调链,并中断事件的执行
if (output === false) return false;
if (typeof previousEventCallBack === 'function') {
output = previousEventCallBack(e);
if(output === false) return false;
}
}
};
// 现在我们可以重构字段的约束校验了
// 由于不使用 CSS 伪类, 我们必须明确地设置 valid 或 invalid 类到 email 字段上
addEvent(window, "load", function () {
// 在这里验证字段是否为空(请记住,该字段不是必需的)
// 如果非空,检查它的内容格式是不是合格的 e-mail 地址
var test = email.value.length === 0 || emailRegExp.test(email.value);
email.className = test ? "valid" : "invalid";
});
// 处理用户输入事件
addEvent(email, "input", function () {
var test = email.value.length === 0 || emailRegExp.test(email.value);
if (test) {
email.className = "valid";
error.innerHTML = "";
error.className = "error";
} else {
email.className = "invalid";
}
});
// 处理表单提交事件
addEvent(form, "submit", function () {
var test = email.value.length === 0 || emailRegExp.test(email.value);
if (!test) {
email.className = "invalid";
error.innerHTML = "I expect an e-mail, darling!";
error.className = "error active";
// 某些旧版浏览器不支持 event.preventDefault() 方法
return false;
} else {
email.className = "valid";
error.innerHTML = "";
error.className = "error";
}
});
该结果如下:
正如你所看到的,建立自己的校验系统并不难。 困难的部分是使其足够通用,以跨平台和任何形式使用它可以创建。 有许多库可用于执行表单校验; 你应该毫不犹豫地使用它们。 这里有一些例子:
独立的库(原生 Javascript 实现):
远程校验
在某些情况下,执行一些远程校验可能很有用。 当用户输入的数据与存储在应用程序服务器端的附加数据绑定时,这种校验是必要的。 一个应用实例就是注册表单,在这里你需要一个用户名。 为了避免重复,执行一个 AJAX 请求来检查用户名的可用性,要比让先用户发送数据,然后因为表单重复了返回错误信息要好得多。
执行这样的校验需要采取一些预防措施:
它要求公开 API 和一些数据;您需要确保它不是敏感数据。
网络滞后需要执行异步校验。这需要一些用户界面的工作,以确保如果校验没有适当的执行,用户不会被阻止。