JavaScript网站设计实践(七)编写最后一个页面 改进表单
一、最后一个页面 contact.html。改进表单
在该页面实现的功能:
- 几乎所有的网站都会有表单填写,对于用户输入和填写的数据,首先我们一般现在前台验证,然后再去后台验证。
在前台最简单的验证:检查必填字段是否填写、填写格式是否符合要求等。
- 每个表单里面,当获取到输入焦点时,令提示文本消失
现在开始动手来写。
1、实现思路
(1)在这个表单里会验证的是必填字段和邮箱格式是否正确。首先,把判断必填字段和邮箱格式分别写在两个函数里;然后在一个validateForm()函数里,根据获取到的className属性值,确定调用哪个函数(className属性值有required和email);最后将这个判断合法性的整合函数valiedateForm()在用户提交数据时调用进来。
function prepareForms(){
for(var i=0; i<document.forms.length; i++){
var thisform = document.forms[i];
resetFields(thisform);
thisform.onsubmit = function(){
return validateForm(this);
}
}
}
(2)关于提示文本消失,给一个if判断,如果表单里的值默认值,则赋值为空,否则当输入焦点离开时,不去改变值。
function resetFields(whichform){ for(var i=0; i<whichform.elements.length; i++){ var element = whichform.elements[i]; //获取每个表单元素 if(element.type == "submit") continue; //如果是表单元素类型是submit,则退出本次循环 if(!element.defaultValue) continue; //如果不是表单元素的默认值,也退出本次循环 element.onfocus = function(){ if(this.value == this.defaultValue){ this.value = ""; } } element.onblur = function(){ if(this.value == ""){ this.value = this.defaultValue; } } } }
defaultValue为表单的默认值,onfocus为获取焦点,onblur焦点离开。
(3)兼容浏览器。不是所有的浏览器都会对点击label元素所包含的的文本,与之相关的表单字段就会获得输入焦点并等待用户输入,所以写个小函数来实现兼容。
function focusLabels(){ //旧浏览器 对象检测 if(!document.getElementsByTagName) return false; //获取元素 var labels = document.getElementsByTagName("label"); //给有for属性的label添加focus()函数 for(var i=0; i<labels.length; i++){ //for循环判断 if(!labels[i].getAttribute("for")) continue; labels[i].onclick = function(){ var id= this.getAttribute("for"); //获取到label中for的值 if(!document.getElementById(id)) return false; //再判断是否存在跟for的值一样的id值 有则添加focus()方法 var element = document.getElementById(id); element.focus(); } } }
给每个label标签的都有一个onclick函数,如果这个label标签有for属性值,并且这个表单里面的某个字段是有存在这个id,则给这个id所在的表单字段一个focus函数。element.focus()
2、代码
(1)contact.html
拷贝template.html,在div的className为content部分,开始写表单内容。
<div id="content"> <h1>联系我们乐队</h1> <form method="post" action="#"> <fieldset> <p> <label for="name">Name:</label> <input type="text" id="name" name="name" value="your name" class="required"/> </p> <p> <label for="email">Email:</label> <input type="text" id="email" name="email" value="your email" class="email required" /> </p> <p> <label for="message">Message:</label> <textarea rows="7" cols="45" id="message" name="message" class="required"> 写下你的留言</textarea> </p> <input class="contact_sub" type="submit" value="留言" /> </fieldset> </form> </div>
(2)修改webdesign.css文件
label{ display: block; } fieldset{ border: 0; } .contact_sub{ width: 100px; height:30px; }
(3)创建contact.js文件
/*******兼容不同浏览器 点击文本即可使与之相关的表单输入获得焦点*****/ function focusLabels(){ //旧浏览器 对象检测 if(!document.getElementsByTagName) return false; //获取元素 var labels = document.getElementsByTagName("label"); //给有for属性的label添加focus()函数 for(var i=0; i<labels.length; i++){ //for循环判断 if(!labels[i].getAttribute("for")) continue; labels[i].onclick = function(){ var id= this.getAttribute("for"); //获取到label中for的值 if(!document.getElementById(id)) return false; //再判断是否存在跟for的值一样的id值 有则添加focus()方法 var element = document.getElementById(id); element.focus(); } } } addLoadEvent(focusLabels); /*****************删除表单默认值*************************/ function resetFields(whichform){ for(var i=0; i<whichform.elements.length; i++){ var element = whichform.elements[i]; //获取每个表单元素 if(element.type == "submit") continue; //如果是表单元素类型是submit,则退出本次循环 if(!element.defaultValue) continue; //如果不是表单元素的默认值,也退出本次循环 element.onfocus = function(){ if(this.value == this.defaultValue){ this.value = ""; } } element.onblur = function(){ if(this.value == ""){ this.value = this.defaultValue; } } } } /*************找到每个表单元素whichform*****************/ function prepareForms(){ for(var i=0; i<document.forms.length; i++){ var thisform = document.forms[i]; resetFields(thisform); thisform.onsubmit = function(){ return validateForm(this); } } } addLoadEvent(prepareForms); /**********表单数据合法性检验 是否已填isFillEd(field)******/ function isFilled(field){ if(field.value.length < 1 || field.value == field.defaultValue){ return false; }else{ return true; } } /***********邮箱格式是否正确****************************/ function isMail(field){ if(field.value.indexOf("@") == -1 || field.value.indexOf(".") == -1){ return false; }else{ return true; } } /***********整合检验表单合法性**************************/ function validateForm(whichform){ //如果表单含有required的className属性值,则调用isFilled for(var i=0; i<whichform.elements.length;i++){ var element = whichform.elements[i]; if(element.className.indexOf("required") != -1){ if(!isFilled(element)){ alert("请填写"+element.name); return false; } } if(element.className.indexOf("email") != -1){ if(!isMail(element)){ alert("请填写正确的邮箱地址"); return false; } } } return true; }
最后,在contact.html页面,加载contact.js文件。
ok了,可以打开谷歌浏览器验证一番。现在在表单必填字段没填写,邮箱地址写错 ,会出现一个对话框。
二、学与思
1、默认值
联系表单里都会有一些默认的“占位符”文本,W3C是这样说的:“如果你无法断定用户端的软件或代理能够对空白的控件做出正确的处理,就一定要在编辑框或文本输入区域里给出一些默认的、占位符性质的字符。【优先级3】”。
默认值美中不足之处就是当准备输入时要手动清除,麻烦。所以写了个小函数,当if判断是默认值时,则把表单字段赋值为空。
2、Form对象
获取到的是input、textarea等
和childNodes.length不一样。form.elements.length只对掉单元素进行统计。
3、数据合法性检验
把判断必填字段和邮箱格式的判断函数写在不同的函数里,然后在一个整合函数中根据表单字段id值不同再进行具体调用。显得更加方便,这样就不用在每个表单字段里面添加这样一个判断函数,我们需要做的就是获取到表单的className属性值,给一个if判断,是required的是就调用isFilled(),如果是email就调用isMail()。最后在用户提交数据时,调用这个整合函数即可。
完整代码:http://pan.baidu.com/s/1mgr39US