
2.1 最简单的表单验证——禁止空白的必填项目
表单验证是一个恒久话题,但其原理则相当简单(见图2-1)。简单的东西更有生命力,用JavaScript语言专门制作的收费表单验证产品有很多。

图2-1 一个表单验证的流程图
2.1.1 最简单表单的HTML结构
网站最基础的模块就是注册,它是一个系统的交互基础。有关其HTML结构,请看【范例2-1】。
【范例2-1 最简单表单的HTML结构】
1. <! DOCTYPE html> 2. <html> 3. <head> 4. <title>最简单表单的HTML 结构</title> 5. </head> 6. <body> 7. <form method="post" action=""> 8. 账户:<input type="text" name="" /><br /><br /> 9. 密码:<input type="password" name="" /><br /><br /> 10. 确认:<input type="password" name="" /><br /><br /> 11. <input type="submit" value="注册"/> 12. </form> 13. </body> 14. </html>
【范例2-1】中第7~12行就是一个注册表单的基本代码,目前我们还做不了任何有用的事情。比如单击“注册”按钮后发布的数据,系统后台是接收不到的,因为input标签中的name没有指定任何参数,这个参数需要和系统后台协商指定。再看看代码运行的效果,如图2-2所示。

图2-2 【范例2-1】Firefox中的运行效果
2.1.2 绑定验证功能
因为用户最后要去单击“注册”按钮,所以我们就在“注册”按钮上添加一个onclick事件属性,引用eg.regCheck(),见【范例2-2】。
【范例2-2 注册事件】
1. ……前面代码略…… 2. <input type="submit" value="注册"onclick="return eg.regCheck(); "/> 3. </form> 4. <script> 5. var eg = {}; //声明一个对象,当作命名空间来使用,本书默认的范例都会以此来方便管理 6. eg.regCheck = function(){ 7. 8. } 9. </script> 10. </body> 11. </html>
当写到【范例2-2】时,必须要让eg.regCheck()函数做些什么才是。比如要获取用户输入的账户信息该怎么办?这时最好给input标签加上一个id属性,JavaScript再通过这个指定的id去取得对应的信息,然后返回验证结果true或false,见【范例2-3】。
【范例2-3 给表单添加验证功能】
1. ……前面代码略…… 2. 账户:<input type="text" name="" id="userid" /><br /><br /> 3. 密码:<input type="password" name="" id="userpwd" /><br /><br /> 4. 确认:<input type="password" name="" id="userpwd2" /><br /><br /> 5. <input type="submit"value="注册"onclick="return eg.regCheck(); "/> 6. </form> 7. <script> 8. var eg = {}; //声明一个对象,当作命名空间来使用,本书默认的范例都会以此来方便管理 9. //定义一个公共函数来获取指定id 元素,减少代码量,提高代码复用率 10. eg.$ = function(id){ 11. return document.getElementById(id); 12. }; 13. eg.regCheck = function(){ 14. var uid = eg.$("userid"); 15. var upwd = eg.$("userpwd"); 16. var upwd2 = eg.$("userpwd2"); 17. if(uid.value == ''){ 18. alert(’账户不能为空!'); 19. return false; 20. } 21. if(upwd.value == ''){ 22. alert(’密码不能为空!'); 23. return false; 24. } 25. if(upwd.value ! = upwd2.value){ 26. alert(’两次密码输入不相同!'); 27. return false; 28. } 29. return true; 30. }; 31. </script> 32. </body> 33. </html>
【范例2-3】第11行的getElementById函数和onclick事件就是前面1.1.3小节提到的DHTML所提供的,限于篇幅,更多信息需要读者自行上网搜寻了解。
这样我们就为表单加上了最简单的验证功能。
2.1.3 绑定验证的另一种方式
【范例2-3】把验证放在“注册”按钮的onclick事件属性里使用,同样还有另一种调用方式,即form标签的onsubmit事件属性,功能一样,完整代码见【范例2-4】。
【范例2-4 form表单绑定验证完整范例】
1. <! DOCTYPE html> 2. <html> 3. <head> 4. <title>最简单表单的HTML 结构</title> 5. </head> 6. <body> 7. <form method="post" action="" onsubmit="return eg.regCheck(); "> 8. 账户:<input type="text" name="" id="userid" /><br /><br /> 9. 密码:<input type="password" name="" id="userpwd" /><br /><br /> 10. 确认:<input type="password" name="" id="userpwd2" /><br /><br /> 11. <input type="submit" value="注册" /> 12. </form> 13. <script> 14. var eg = {}; //声明一个对象,当作命名空间来使用,本书默认的范例都会以此来方便管理 15. //定义一个公共函数来获取指定id 元素的值,减少代码量,提高代码复用率 16. eg.$ = function(id){ 17. return document.getElementById(id); 18. }; 19. eg.regCheck = function(){ 20. var uid = eg.$("userid"); 21. var upwd = eg.$("userpwd"); 22. var upwd2 = eg.$("userpwd2"); 23. if(uid.value == ''){ 24. alert(’账户不能为空!'); 25. return false; //返回false 就会阻止表单form 提交 26. } 27. if(upwd.value == ''){ 28. alert(’密码不能为空!'); 29. return false; //返回false 就会阻止表单form 提交 30. } 31. if(upwd.value ! = upwd2.value){ 32. alert(’两次密码输入不相同!'); 33. return false; //返回false 就会阻止表单form 提交 34. } 35. return true; //返回true 就会提交表单form 36. }; 37. </script> 38. </body> 39. </html>
【范例2-4】和【范例2-3】类似,只是调用的地方不同,所谓条条大路通罗马,有很多算法都可以达到相同的目的,只是根据情况而定,两个范例的运行效果都一样,见图2-3。

图2-3 【范例2-3】和【范例2-4】的运行效果
前面的范例都是把JavaScript和HTML代码写在一起,也可以将js代码直接保存为html格式或htm格式的文件让浏览器来运行。HTML文档最常用的扩展名是html,而扩展名htm是因为像DOS这样的旧操作系统限制扩展名为最多3个字符,所以也允许使用htm扩展名。现在htm扩展名使用得比较少,但是仍旧受到支持。
从本章的范例可以看出,笔者使用了eg这样的全局对象变量来存储自定义的各种方法。这称为“单全局变量”——这样做的目的是减少“环境污染”,正所谓环保无处不在,环保的好处在于不同人编写的代码、不同项目的代码都可以放心大胆地使用,而不用担心冲突,另外就是利于维护,看看图2-4就能明白。使用单全局变量的著名范例有jQuery库、YUI工具等。
比单一更少的是零全局变量,这是一个极端特例,如果脚本短小,且不需要对外提供交互接口时就可以这样做,但一般都要提供至少一个以上的交互接口。

图2-4 全局变量污染对比