DHTML5(控件动态效果综合应用与表单校验)


----android培训 java培训、期待与您交流!----

1.动态添加附件:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>动态添加附件</title>
<script type="text/javascript" src="JS/documentTools.js"></script>
<style type="text/css">
table{
  border:1px solid #00F;
}
table td{
  border:1px solid #999;
}
</style>
<script type="text/javascript">
 function addAttachment(){
    var count=0;
    var tableNode=byID("tableID");
    var trNode=tableNode.insertRow();
    trNode.id="tr_"+(++count);//为每个行对象绑定一个编号
    
    trNode.insertCell().innerHTML="<input type='file'/>";
    //trNode.insertCell().innerHTML
    //="<a href='javascript:void(0)'onclick='deleteAttachment("+count+")'>删除</a>";
  trNode.insertCell().innerHTML
    ="<a href='javascript:void(0)'onclick='deleteAttachment_2()'>删除</a>";
 
 }
 /*
 删除可以有两种做法:
 1.利用tableNode.deleteRow(index)/rows.remove(index)
 2.利用tbodyNode.removeChild(rowObject)
 三种删除动作会导致rows集合rowObject的index时刻该变
 第一种需要根据index删除,操作起来相当麻烦
 第二种获取删除行对象,那么可以为其手动指定一个编号便于获取.
 */
 function deleteAttachment(count){
     var trNode=byID("tr_"+count);
     trNode.parentNode.removeChild(trNode);
 }
 
//简单做法,不为每行绑定一个id,利用事件源对象以及节点之间关系
 function deleteAttachment_2(){
    var trNode=event.srcElement.parentNode.parentNode;
    trNode.parentNode.removeChild(trNode);
 }
</script>
</head>

<body>
<table id="tableID">
 <tr>
  <td><a href="javascript:void(0)" onclick="addAttachment()">点击添加附件</a></td>
 </tr>
</table>
</body>
</html>

动态添加附件

在这个例子中想到的一个问题:

JS单引号与双引号问题:
trNode.insertCell().innerHTML
    ="<a href='javascript:void(0)'onclick='deleteAttachment("+count+")'>删除</a>";
该如何书写传入字符串常量?
  正确书写方式"<a href='javascript:void(0)'onclick='deleteAttachment(\"abc\")'>删除</a>";
 
  var str="abc"; 
  ="<a href='javascript:void(0)'onclick='deleteAttachment("+str+")'>删除</a>";//失败
  可以这样书写:
  var str="\"abc\""//外层的""表示他是一个字符串,内层\" \"当它在" "内部时把abc当成字符串解析
                   //str="abc",这样书写会报:abc undefined 被当成未初始化的变量
  "<a href='javascript:void(0)'onclick='deleteAttachment("+str+")'>删除</a>";

由该篇博文得到的启发:http://cindysaj.iteye.com/blog/669797 

2.邮件列表操作:(注意删除邮件)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>邮件列表综合功能</title>
<script type="text/javascript" src="JS/documentTools.js"></script>
<style type="text/css">
 table{
     border-collapse:collapse;
     width:500px;
 }
 table td{
     border:1px solid #999;
     padding:10px;
 }
 table th{
   border:1px solid #999;
     padding:10px;
     background-color:#099;
  }
 .evenLine{
     background-color:#CCC;
     
 }
 .oddLine{
     background-color:#999;
 }
 .highLight{
     background-color:#FF9;
     
}
</style>
<script type="text/javascript">
 /*行颜色间隔显示,鼠标点击颜色变化,离开恢复原来颜色*/
  window.onload=loadColor;
  function loadColor(){
       var tableNode=byID("mailList");
         for(var i=1;i<tableNode.rows.length-1;++i){
           if(i%2==0)
               tableNode.rows[i].className="evenLine";
           else
             tableNode.rows[i].className="oddLine";
         
          var oldClass;
          tableNode.rows[i].onmouseover=function(){
             oldClass=this.className;
             this.className="highLight";
          }
          
          tableNode.rows[i].onmouseout=function(){
             
             this.className=oldClass;
          } 
         
     }
    
 }
 
 /*checkAll对应的事件处理方式*/
  function checkAll(){
    var checkboxNodes=byName("choose");
    var checkAllNodes=byName("selectAll");
    for(var index=0;index<checkboxNodes.length;++index)
          checkboxNodes[index].checked=event.srcElement.checked;
        
     event.srcElement==checkAllNodes[0]?
     checkAllNodes[1].checked=false:checkAllNodes[0].checked=false;
         //这里为了改变另一个已经被点击的全选的checked为false
  }


/*反选,取消全选时置全选的checked为false*/
function cancelCheckAll(checkAllNodes){
  for(var index=0;index<checkAllNodes.length;++index)
       checkAllNodes[index].checked=false;
}

/*将全选,反选,取消全选三个按钮用一个函数:*/
 function choice(input){
    var checkboxNodes=byName("choose");
    var checkAllNodes=byName("selectAll");
    for(var index=0;index<checkboxNodes.length;++index)//全选,取消全选,反选均需要获取与设置
                                                         //checkbox状态,都需要遍历
        switch(input.value){
           case "全选":checkboxNodes[index].checked=true;break;
           case "取消所选":
                           checkboxNodes[index].checked=false;
                           cancelCheckAll(checkAllNodes);break;
           case "反选":cancelCheckAll(checkAllNodes);
                       checkboxNodes[index].checked=!checkboxNodes[index].checked//对当前状态取反
         }
}
 
 /*delSelected对应的事件处理方式*/
  function delSelected(){
      var flag=window.confirm("是否删除所选邮件?");
      var checkboxNodes=byName("choose"); 
      var deleteTrArr=new Array(),pointer=0;//为了便于操作把要删除的行先保留
      if(flag){
          for(var index=0;index<checkboxNodes.length;++index)
               if(checkboxNodes[index].checked){      
               deleteTrArr[pointer++]=checkboxNodes[index].parentNode.parentNode;
           }
          var tbodyNode=byTagName("tbody")[0];
          for(var index=0;index<deleteTrArr.length;++index)
            tbodyNode.removeChild(deleteTrArr[index]);
          
          loadColor();//删除行会改变原有的行的奇偶排列要把行,需要颜色重新加载下
          
          alert("删除成功!")
       }
  }
</script>
</head>
<body>
 <table id="mailList">
   <tr>
     <th><input type="checkbox"  name="selectAll" onclick="checkAll()"/>全选</td>
     <th>发件人</td>
     <th>邮件内容</td>
   </tr>
    <tr>
     <td><input type="checkbox" name="choose"/></td>
     <td>张三1</td>
     <td>新的邮件</td>
   </tr>
   <tr>
     <td><input type="checkbox" name="choose" /></td>
     <td>张三2</td>
     <td>新的邮件</td>
   </tr>
   <tr>
     <td><input type="checkbox" name="choose"/></td>
     <td>张三3</td>
     <td>新的邮件</td>
   </tr>
   <tr>
     <td><input type="checkbox" name="choose"/></td>
     <td>张三4</td>
     <td>新的邮件</td>
   </tr>
    <tr>
     <td><input type="checkbox" name="choose"/></td>
     <td>张三5</td>
     <td>新的邮件</td>
   </tr>
   <tr>
     <td><input type="checkbox" name="choose"/></td>
     <td>张三6</td>
     <td>新的邮件</td>
   </tr>
   <tr>
     <td><input type="checkbox" name="choose"/></td>
     <td>张三7</td>
     <td>新的邮件</td>
   </tr>
   <tr>
     <th><input type="checkbox" name="selectAll" onclick="checkAll()"/>全选</td>
     <th colspan="2">
       <input type="button" value="全选" onclick="choice(this)"/>&nbsp;
       <input type="button" value="取消所选" onclick="choice(this)"/>&nbsp;
       <input type="button" value="反选" onclick="choice(this)"/>&nbsp;
       <input type="button" value="删除所选邮件" onclick="delSelected()"/>
     </th>
    </tr>
 
 </table>
</body>
</html>

邮件列表

犯的错误:
   tableNode.rows[i].onmouseover=function(){
             oldClass=tableNode.rows[i].className
             tableNode.rows[i].className="highLight";
          }
   //注意在页面加载时,JavaScript引擎先把循环执行完,为每一个行对象注册该事件
   //那么i的值在不断自增,当页面加载完循环执行结束.
   //当触发该事件时,i的值为9->tableNode.rows[i]为undefined
   //我这里把事件的注册和事件的触发混淆,
   //这里仅仅相当于一个赋值语句:
   //tableNode.rows[i].onmouseover指向一个匿名函数对象

当事件与函数同名:
window.onload=function(){
  alert(3);
}
  function onload(){
   alert(10);    
}
//IE10 下debug发现window.onload已经指向onload指向的函数对象
//但是并没有执行,最好不要同名.

3.表单验证1(主要熟悉JS中一些方法):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>表单验证1</title>

<script type="text/javascript">
 var submitFlag=false;//防止上来就点提交
 function printText(spanNode,flag){
    if(flag){
        spanNode.innerHTML="<font color='green'>√</font>"; 
        submitFlag=flag;
    }
    else{
      spanNode.innerHTML="<font color='red'>×</font>"; 
      submitFlag=flag;
    }
 }
 function checkUser(){
 var userName=document.forms[0].user.value;//document.forms返回所有form对象集合
                                           //id,tagname,name也可获取表单对象
  var regex=new RegExp("^[a-zA-Z]{5}$")//JS中的正则和Java中的正则写法有略微区别
                                     //[a-zA-Z]{5}该模式会匹配输入文本框中满足条件字符串的子串
                                     //12abcde也将符合要求,它没有像Java中的正则限定位数为5位
                                     //这时候必须加上^,$:分别匹配字符串的开始位置和结束位置
                                     //在这里相当于拿整个字符串与模式匹配
  var spanNode=document.getElementById("checkUser");
  printText(spanNode,userName.match(regex));
 }
 function checkPwd(){
    var userPwd=document.forms[0].pwd.value;
    var spanNode=document.getElementById("checkPwd");
    var regex=/^\d{6}$/; //JS正则特有写法,这里\d的\不需要转义,只有在字符串在需要
    printText(spanNode,(regex.test(userPwd)));//test则依据是否有匹配返回true/false
 }
 function checkConfPwd(){
     var userConfPwd=document.forms[0].confirmPwd.value;
     var userPwd=document.forms[0].pwd.value;
     var spanNode=document.getElementById("confirmPwd");
     printText(spanNode,userConfPwd==userPwd);
 }
 function checkMail(){
    var userMail=document.forms[0].mail.value;
    var regex=/^\w+@\w+(\.\w+)+$/;
    var spanNode=document.getElementById("mailInfo");
    printText(spanNode,regex.test(userMail));
 }
function beforeSubmit(){
    submitFlag?event.returnValue=true:event.returnValue=false;
    //以上有一步失败,将取消提交动作
    //视频中提到,如果用户输入完所有项并且都符合要求,在submit前,又去修改了用户名
//
而输入光标未移动,又去点提交(注意:虽然你输入光标未移动,但是你去点击submit,userName会失去焦点再次触发onblur事件,那么就会在次校验)
}
</script>
</head>

<body>
<form name="form" action="http://127.0.0.1" onsubmit="beforeSubmit()"><!--onsubmit在表单将要被提交时触发-->
用户名称:<input type="text"  name="user" onblur="checkUser()"/>
 <span id="checkUser">用户名错误</span>
 <br/>
 <br/>
 输入密码:<input type="text" name="pwd" onblur="checkPwd()"/> 
 <span id="checkPwd"></span>
 <br/>
  <br/>
 确认密码:<input type="text" name="confirmPwd" onblur="checkConfPwd()"/>
  <span id="confirmPwd"></span>
 <br/>
 <br/>

 邮箱地址:<input type="text" name="mail" onblur="checkMail()"/>
   <span id="mailInfo"></span>
 <br/>
 <input type="submit" value="提交"/>
</form>
</body>
</html>

JS中String对象的match方法: (以下内容摘自W3CSchool)
     match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。这个方法的行为在很大程度上有赖于 regexp 是否具有标志 g。

    1.如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配(搜寻符合模式的第一个子串,如果有定位符另考虑).如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式(正则表达式中的组)匹配的文本。
    除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。
    例如:
      var s = "The rainna in"
      re=new RegExp("ai(nn)(a)+");
      r = s.match(re);  
      alert(r+"..."+r.index+"..."+r.input)
      /*  ainna,nn,a...5...The rainna in  */
   2.如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串,而且也没有 index 属性或 input 属性。

onsubmit="return beforeSubmit()" //beforeSubmit要有返回值

4.表单校验2:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>表单校验2</title>
<style type="text/css">
table{ 
    border-collapse:collapse;
}
table td,table th{
  border:1px solid #00F;
  padding:10px;
}
table td{
    background-color:#6C9;
}
table th{
    background-color:#F90;    
}

/*当文本框获取焦点的样式*/
.focus{
    background-color:#9C0;
}
.original{
    border:1px solid  #CCC;
    background-color:#FFF;
}
.errorBorder{
   border:2px solid red;
 }
/*错误信息样式*/
.errorInfor{
    color:#B50000;
    display:none;
}
</style>
</head>
<script type="text/javascript">
 function changeTextBox(input){
      input.className="original";
      if(input.name=="userName")//页面打开,将焦点设置到userName文本框
        input.focus();
      input.onfocus=function(){
        input.className="focus";
      }
      
  } 
  
  window.onload=function(){
     var formNode=document.forms[0];
     //为每个input控件注册focus事件和加载共同样式
     changeTextBox(formNode.userName);
     changeTextBox(formNode.userPwd);
     changeTextBox(formNode.rePwd);
     changeTextBox(formNode.mail);
  }

  
  function check(inputNode,regex,divID){
    var flag=false;//在最后提交时会用到
    var divNode=document.getElementById(divID);
    if(regex.test(inputNode.value)){
          inputNode.className="original";
        divNode.style.display="none";//当用户输错,再次输入正确,隐藏错误信息
        flag=true;
    }
    else{
       inputNode.className="errorBorder";
       divNode.style.display="block";
    }
    return flag;
  }
  function checkUser(userNode){
     return check(userNode,/^\w{3,5}$/,"userError");
  }
  function checkPwd(pwdNode){
    return check(pwdNode,/^\w{3,5}$/,"pwdError");
  }
  function checkRePwd(rePwdNode){
     var flag=false;
    var userPwdNode=document.getElementsByName("userPwd")[0];
    var divNode=document.getElementById("pwdNotMatch");
    if(rePwdNode.value==userPwdNode.value){
        rePwdNode.className="orginal";
        divNode.style.display="none";
        flag=true;
    }
    else{
        rePwdNode.className="errorBorder";
        divNode.style.display="block";
    }
    return flag;
  }
  
  function checkMail(mailNode){
     return check(mailNode,/^\w+@\w+(\.\w+)+$/,"mailError");
  }
  
 /*表单提交onsubmit事件对应处理方式*/
 function submitForm(){
     var formNode=event.srcElement;
     if(checkUser(formNode.userName)&&checkPwd(formNode.userPwd)
       &&checkRePwd(formNode.rePwd)&&checkMail(formNode.mail))
        event.returnValue=true;
     else
       event.returnValue=true;
 }
</script>
<body>
<form onsubmit="submitForm()">
<table>
 <tr>
  <th>注册表单</th>
 </tr>
 <tr>
    <td>
      <div>用户名</div>
      <input type="text" name="userName" onblur="checkUser(this)"/>
      <div class="errorInfor" id="userError">用户名错误,请按要求输入</div>    
      <div>用户名必须是3-5位,由字母(a-z),数字(0-9),下划线(_)组成</div>
      
    </td>
 </tr>
 <tr>
    <td>
    <div>密码</div>
     <input type="password" name="userPwd"onblur="checkPwd(this)"/>
     <div class="errorInfor" id="pwdError">密码格式错误,请按规范输入</div>
     <div>密码必须是3-5位,由字母(a-z),数字(0-9),组成</div>
     
    </td>
 </tr>
 <tr>
    <td>
    <div>确认密码</div>
     <input type="password" name="rePwd" onblur="checkRePwd(this)"/>
     <div class="errorInfor" id="pwdNotMatch">两次密码输入不一致</div>
     </td>
 </tr>
 <tr>
    <td>
     <div>邮箱地址</div>
     <input type="text" name="mail"  onblur="checkMail(this)"/>
     <div class="errorInfor" id="mailError">邮箱地址错误,请按要求填写</div>
    </td>
 </tr>
 <tr>
    <th>
      <input type="submit" value="提交" style="width:100px"/>
    </th>
 </tr>
</table>
</form>
</body>
</html>

表单验证

5.关于测试以上表单校验发现的一个细节: (以下测试两种方法完成错误信息的隐藏与显示的测试)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<style type="text/css">
 .errorInfor{
    color:#B50000;
    display:none; 
 }
</style>
<script>
  function submitForm(formNode,index,checkUser){
     var inputNode=document.forms[index].userName
      if(checkUser(inputNode))
        event.returnValue=true;
      else
        event.returnValue=false;
  }

  function checkUser(inputNode){
    var divNode=document.getElementById("divID");
    if(inputNode.value=="abc"){
      divNode.style.display="none";
      return true;
    }
    else{
      divNode.style.display="block";
      return false;  
    }
  }

  function checkUser_2(inputNode){
   var divNode=document.getElementById("divUser");
    if(inputNode.value=="efg"){
     
      return true;
    }
    else{
     divNode.innerHTML="用户名错误".fontcolor("red");
      return false;  
    }       
  }
</script>
</head>

<body>

 <form onsubmit="submitForm(this,0,checkUser)">
   <input type="text" name="userName" onblur="checkUser(this)"/>
   <span class="errorInfor" id="divID">用户名错误</span><br/>
   <input type="submit" value="提交"/>
 </form>
 <br/>
 
 
 
 
 <form onsubmit="submitForm(this,1,checkUser_2)">
   <input type="text" name="userName" onblur="checkUser_2(this)"/>
   <div id="divUser"></div>
   <input type="submit" value="提交"/>
 </form>
</body>
</html>

1.采用页面写入错误信息,刚开始隐藏方式(display:none/block/inline)

有个细节:
当用户在点提交前,有错误的数据,再去修改正确后,此时输入光标仍然在文本框中,并且有错误提示.
此时点击submit
第一次点击:错误信息消除
第二次点击:提交.
2.而在JS中写入错误信息(innerHTML),则按上述情况只点击一次

posted @ 2013-08-27 21:10  伊秋  阅读(781)  评论(0编辑  收藏  举报