一. HTML DOM常用对象: ——没有jQuery,没有框架时的过渡
1. HTML DOM对个别常用的比较复杂的对象提供了简化写法
2. <img>的简化:
(1). 唯一的简化: 创建img
a. 旧DOM: var img=document.createElement("img");
b. HTML DOM: var img=new Image();
(2). 强调: 只有两个元素可以new,其余元素都不能用new轻易创建
a. new Image()
b. var option=new Option()
3. <select>元素:
(1). options属性: 可直接获得select下所有直接子元素option的集合
(2). 创建<option>时: var option=new Option()
4. <table>元素: 逐级管理:
(1). Table对象管着行分组对象
a. table对象可以添加行分组对象
1). 旧DOM: 2步:
i. var tbody=document.ceateElement("tbody") //创建行分组对象
ii. table.appendChild(tbody) //将行分组添加到table中
2). HTML DOM:
var tbody=table.createTBody()
强调: 一句话办两件事: 既创建行分组对象,又将行分组添加到table中
3). 出了createTBody()还有:
i. var thead=table.createTHead();
ii. var tfoot=table.createTFoot();
b. table对象可以删除行分组对象
1). table.deleteTHead()
2). table.deleteTFoot()
3). 没有table.deleteTBody()
c. table对象可以获取某个行分组对象
1). table.tHead
2). table.tFoot
3). table.tBodies[i]
说明: HTML标准规定,table中可以包含多个tbody,所以table将内部的可能多个tbody元素都放在tBodies数组中,我们可通过下标i,来访问table中第i个tbody对象。
(2). 行分组对象管着行对象:
a. 行分组对象可添加行:
1). 旧DOM: 2步
var tr=document.createElement("tr"); //先创建新行对象
tbody.appendChild(tr); //再将新行对象追加到行分组中
2). HTML DOM: var tr=行分组.insertRow()
插入 新行
说明: insertRow()一个函数办两件事,既创建新行对象,又将新行对象追加到行分组中
3). 固定套路:
i. 其实insertRow(i) 可在中间i位置插入一个新行,原位置的行被向后挤一位
ii. 想在开头插入一个新行 insertRow(0)
b. 行分组对象可删除行:
1). 行分组.deleteRow(i)
2). 坑: 用行分组对象删除行时,i必须是要删除的行在行分组内的相对位置
3). 问题: 如果看不出一行在行分组的下标位置是几,还可通过要删除的行对象的rowIndex属性,来获得行的下标位置。但是,行对象的rowIndex属性是这一行在整个表中的下标位置!不是在行分组内的相对位置!所有行的rowIndex属性,因为受到表头行的影响,很可能和行在行分组内的下标位置序号是错位的。
tbody.deleteRow(tr.rowIndex) 很可能删的不是想删除的一行,很可能是要删除行的下一个
4). 解决: 今后,只要删除表格中的行,都应用table来删除,而不是用行分组
i. table.deleteRow(tr.rowIndex)
ii. 因为主语变成了table,deleteRow要求使用的下标范围也变成了行在整个table中的下标。整个要求刚好和tr.rowIndex的意思吻合!
c. 获取一行: 行分组.rows[i]
1). 说明:行分组已经将内部的所有tr对象,放在了一个rows属性集合中,可通过下标方式,访问行分组中第i行
(3). 行对象管着格对象:
a. 行对象可添加一个新格:
1). 旧DOM: 2步:
i. var td=document.createElement("td"); //创建新的td对象
ii. tr.appendChild(td) //将td对象追加到tr中
2). HTML DOM: var td=tr.insertCell()
插入新格
说明: insertCell()一个函数做两件事,既创建新的td对象,又将td对象追加到tr中
b. 行对象还可删除一个格: tr.deleteCell(i)
c. 行对象还可获得一个格: tr.cells[i]
1) 说明: 行已经将内部的所有td对象,放在了一个cells属性集合中,可通过下标方式,访问行中第i个格
(4). 示例: 简化动态创建表格的例子
<head> <title>动态创建表格</title> <meta charset="utf-8" /> <style> table{600px; border-collapse:collapse; text-align:center; } td,th{border:1px solid #ccc} </style> </head> <body> <div id="data"> <table> <thead> <tr> <th>姓名</th> <th>薪资</th> <th>年龄</th> </tr> </thead> </table> </div> <script> var json=[ {"ename":"Tom", "salary":11000, "age":25}, {"ename":"John", "salary":13000, "age":28}, {"ename":"Mary", "salary":12000, "age":25} ]; //找到table对象 //本例中: 查找id为data下的table对象 var table=document.querySelector("#data>table") //创建一个tbody元素,追加到table中 // var tbody=document.createElement("tbody"); // table.appendChild(tbody); var tbody=table.createTBody(); //遍历json数组中每个员工对象 for(var emp of json){ //每遍历一个员工对象,就创建行<tr>,追加到tbody中 // var tr=document.createElement("tr"); // tbody.appendChild(tr); //var tr=tbody.insertRow();//末尾追加新行 var tr=tbody.insertRow(0);//总是在开头插入新行 //每遍历到一个员工,就继续遍历员工对象内的每个属性值 for(var key in emp){ //每遍历一个属性值,就创建一个td,并将td追加到tr中,设置td的内容为emp对象中当前属性的属性值 // var td=document.createElement("td"); // tr.appendChild(td); var td=tr.insertCell(); td.innerHTML=emp[key]; } } </script> </body> |
5. 表单:
(1). 获取表单元素:
a. 旧DOM:
1). 有name属性的表单元素: 表单.getElementsByName("name")
2). 没有name属性的表单元素: 表单.getElementsByTagName("标签名")
b. HTML DOM:
1). form对象已经将表单中的所有表单元素提前都保存在了一个elements属性集合中。所以,可通过: 表单.elements[i 或 id 或 name] 方式获得表单中任意一个表单元素
强调: 表单.elements集合中只包含四大类表单元素,不包含其他非表单元素
(input select textarea button)
2). 如果有name属性的表单元素,还可进一步简写为: 表单.name名
c. form.length 获得表单中所有表单元素的个数 == form.elements.length
(2). 让表单元素获得焦点: 表单元素.focus()
(3). 示例: 实现自定义表单提交按钮
<html> <head> <meta charset="UTF-8"> <title>实现带样式的表单验证</title> <style> table{700px} td:first-child{60px} td:nth-child(2){200px} /*IE*/ td:first-child+td{200px} td span{color:red} /*隐身斗篷!谁穿上,谁就隐藏*/ .vali_info{ /*在页面刚加载时,让每个文档框旁边的div提示穿上,暂时隐藏文本框右侧的提示信息*/ display:none; } /*第一个需求时,当文本框失去焦点时,让文本框旁边的div显示出来!也就是清除div的class。*/ .txt_focus{ border-top:2px solid black; border-left:2px solid black; } .vali_success,.vali_fail{ background-repeat:no-repeat; background-position:left center; display:block; } /*专门定义提示信息div在验证通过时的样子*/ /*第二个需求中,当文本框失去焦点,验证文本框的内容,如果通过,就给文本框旁边的div设置class为vali_success*/ .vali_success{ background-image:url("images/ok.png"); padding-left:20px; 0px;height:20px; overflow:hidden; } /*专门定义提示信息div在验证失败时的样子*/ /*第二个需求中,当文本框失去焦点,验证文本框的内容,如果不通过,就给文本框旁边的div设置class为vali_fail*/ .vali_fail{ background-image:url("images/err.png"); border:1px solid red;
color:Red; padding-left:30px; } </style> </head> <body> <form id="form1"> <h2>增加管理员</h2> <table> <tr> <td>姓名:</td> <td> <input name="username"/> <span>*</span> </td> <td> <div class="vali_info"> 10个字符以内的字母、数字或下划线的组合 </div> </td> </tr> <tr> <td>密码:</td> <td> <input type="password" name="pwd"/> <span>*</span> </td> <td> <div class="vali_info">6位数字</div> </td> </tr> <tr> <td></td> <td colspan="2"> <!--以下两个元素都放在<form>内,都会自动提交!--> <!-- <input type="submit" value="保存"/> --> <!-- <button>保存</button> --> <!--自从有了ajax之后,就再不用表单提交了!--> <input type="button" value="保存"> <input type="reset" value="重填"/> </td> </tr> </table> </form> <script> //第一个需求: 当文本框获得焦点时,让文本框旁边的div显示出来 //DOM 4步 //1. 查找触发事件的元素 //本例中: 文本框获得焦点,所以应该按name属性查找两个文本框 // var txtName=document.getElementsByName("username")[0] // // ↑ // var txtPwd=document.getElementsByName("pwd")[0]; // // ↑ //简写: //先获得表单元素对象: var form=document.forms[0]; console.log(form.elements); var txtName=form.username; var txtPwd=form.pwd; console.log(txtName) console.log(txtPwd) //2. 绑定事件处理函数 //本例中: 两个按钮都是获得焦点时触发事件 // 当获得焦点时,自动执行 txtName.onfocus=txtPwd.onfocus=function(){ //3. 查找要修改的元素 //本例中: 查找当前文本框的爹的下一个兄弟的唯一的一个孩子 var div=this.parentNode.nextElementSibling.children[0] console.log(div); //4. 修改元素 //本例中:清楚div的隐身斗篷 div.className=""; } //页面一加载,就让姓名文本框获得焦点 txtName.focus(); //第二个需求: 当文本框失去焦点时,验证文本框的内容,如果验证通过,修改旁边的div为验证通过的样子,如果验证失败,修改旁边的div为验证失败的样式 //1. 查找触发事件的元素(上一步已完成) //2. 绑定事件处理函数 //本例中: 当文本框失去焦点时自动执行操作 // 当失去焦点 txtName.onblur=function(){ //this->txtName; //先定义正则表达式: var reg=/^w{1,10}$/; //调用validate()函数 validate(this,reg) //里边的this->window! } // 验证 function validate(txt,reg){ //因为需要获得当前要验证哪个文本框对象,所以定义形参txt,调用时,必须传入要验证的文本框对象,才能正常执行 //又因为两个验证的正则表达式各不相同,所以定义reg形参,调用时,必须传入这次验证要使用的正则表达式,才能正常执行! //3. 查找要修改的元素 //本例中: 查找当前文本框的爹的下一个兄弟的唯一的一个孩子 var div=txt.parentNode.nextElementSibling.children[0] //4. 修改元素 //如果用正则 验证当前文本框的内容 通过 if( reg.test( txt.value)==true){ div.className="vali_success"; return true; }else{//否则如果验证当前文本框的内容未通过 div.className="vali_fail"; return false; } } txtPwd.onblur=function(){ //this->txtPwd //先定义正则表达式: var reg=/^d{6}$/; //调用validate()函数 validate(this,reg) //里边的this->window! } //点击保存按钮,重新验证之前所有文本框,只有所有文本框都验证通过,才用ajax提交表单 //本例中: 先找到input type="button"的元素 //旧DOM: var btn=form.getElementsByTagName("input")[2] //HTML DOM: var btn=form.elements[2];//所有表单元素中正数第3个元素 //form.elements[form.length-2]//倒数第2个表单元素 console.log(btn); //为按钮绑定单击事件 btn.onclick=function(){ //this->btn->保存按钮 //如果验证姓名文本框未通过 //1. this要改为要验证的文本框对象 //2. reg规则要写死在这里 //3. 如果想知道是否验证通过,还需要给validate方法添加返回值,返回验证结果! if(validate(txtName,/^w{1,10}$/)==false){ //就让姓名文本框获得焦点 txtName.focus(); }else if(validate(txtPwd,/^d{6}$/)==false){//否则如果验证密码框未通过 //就让密码框获得焦点 txtPwd.focus(); }else{//否则如果前两个都通过了 //就用ajax提交表单内容 alert("用ajax提交表单"); //将来然哥教的ajax代码,写这里 } } </script> </body> |