JavaScript编程中最基本的就是DOM编程,DOM是 Document Object Model文本对象模型,就是对DOM对象进行编程的过程。
Java语言和Js都有针对于DOM的编程,两者类似,主要是有一套DOM编程的规范,两者都遵循这样的规范。
这里主要讲Js的DOM编程API
DOM是针对xml(html)基于树的API
DOM树就是节点Node的层次
DOM将文档作为一颗树进行处理,定义了Node节点接口,用节点表示xml中各种信息;
节点分为三种类型:元素节点、属性节点、文本节点
当中。属性节点和文本节点都是元素节点的子节点,元素节点的子节点能够是属性节点、文本节点,也能够是元素节点
属性节点是元素节点的属性。能够直接通过属性的方式操作
文本节点是元素节点的子节点。通常为文本的形式。
一个简单的样例:
能够看出js中的对象以及方法的调用
window和document都是js的对象,onload和onclick都是对象的事件,能够通过为事件赋值函数的方法,在函数中指定事件发生时,要运行的操作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
//1.window是js中的一个对象,onload是该对象的一个事件,为其赋值一个函数
//即:在window对象的onload事件触发时,载入后边的函数
window.onload = function(){
//2.利用对象document的方法getElementsByTagName("")从DOM中获取节点对象。并取得第一个对象
var btn = document.getElementsByTagName("button")[0];
//3.为对象btn的onclick事件赋值函数。当事件触发时。载入后边的函数
btn.onclick = function(){
//4.弹出"helloworld"
alert("helloworld");
}
}
</script>
</head>
<body>
<button>Click me!</button>
</body>
</html>
1、js代码写在什么位置
js代码的位置一般写在html文档中的head节点下的title子节点后边。
js代码也能够和html代码耦合着写。这样针对于比較少的js代码,可是一般不建议这样写:
<body>
<!-- html和js代码耦合在一起 ,代码少的话,能够这样,可是一般不这样写-->
<button onclick="alert('helloworld')">Click me!</button>
</body>为节点button的onclick属性事件直接赋值函数。必需要html文档全然载入之后。才干获取节点,所以能够把js代码放在html文档之后。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<button >Click me!</button>
</body>
</html>
<!-- 在整个html文档载入之后,获取当中的节点,js代码放在html文档之后 -->
<script type="text/javascript">
var btns = document.getElementsByTagName("button");
alert(btns.length);//输出结果为1
</script>缺点是:不符合写js代码的习惯通常将js放在titile的后边,等待文档载入后才运行js代码的操作是为window.onload事件赋值函数操作。
window.onload事件在文档被全然载入后触发。
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
window.onload = function(){
//全部的js代码写在window.onload赋值的函数中
var btns = document.getElementsByTagName("button");
alert(btns.length);//输出结果为1
}
</script>
</head>
2、获取节点
获取元素节点
获取元素节点有三种方法:依据id获取、依据标签名获取元素集合、依据name属性获取元素集合
基本都是依据document对象的方法获取。当中getElementsByTagName依据标签名获取,这种方法是Node接口的方法。不论什么节点对象都有这种方法。
能够用这种方法获取指定节点的子节点
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
window.onload = function(){
//1.依据节点的id获取节点对象。注意在编写html文档时,id 要唯一
//getElementById为document对象的方法
var bjNode = document.getElementById("bj");
alert(bjNode);
//2.使用标签名获取指定节点的集合
//getElementsByTagName方法事Node接口的方法,即不论什么节点对象都有该方法
var lis = document.getElementsByTagName("li");
alert(lis.length);//值为8
//即不论什么节点对象都有该方法getElementsByTagName
//获取指定节点city的li子节点的个数
var cityNode = document.getElementById("city");
var cityLis = cityNode.getElementsByTagName("li");
alert(cityLis.length);//输出值为4
//3.依据元素的name属性来获取指定节点的集合,由于名字可反复。故结果为集合
var genderNode = document.getElementsByName("gender");
alert(genderNode.length);//输出值为2
//若HTML元素自身未定义name属性。则该方法对于IE 无效,使用该方法时需慎重
//li元素本身没有name属性
var bjNode2 = document.getElementsByName("BeiJing");
alert(bjNode2.length);
}
</script>
</head>
<body>
<p>你喜欢哪个城市?</p>
<ul >
<li >北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<br/>
<br/>
<p>你喜欢哪款单机游戏?</p>
<ul >
<li >红警</li>
<li>实况足球</li>
<li>极品飞车</li>
<li>魔兽</li>
</ul>
gender
<input type="radio" name="gender" value="male"/>Male
<input type="radio" name="gender" value="female"/>Female
</body>
</html>
获取属性节点
读写属性节点,就是读写元素节点的属性。通过元素节点"."的方式获取和读写属性
先获取元素节点,再通过元素节点.得到属性值
获取元素节点的子节点
获取元素节点的子节点,也是先获取到元素节点,
通过元素节点的childNodes获取元素节点的全部子节点,
通过getElementsByTagName()获取指定标签子节点,
通过firstChild和lastChild获取第一个子节点和最后一个子节点。
获取文本节点
文本节点一定是元素节点的子节点。先通过获取元素节点,再定位到文本节点,通过文本节点的nodeValue属性读写文本值。
3、两个练习
for循环和函数中的this
练习1:点击全部li标签元素时,弹出该元素节点的文本值
for循环,变量都是var定义的for(var i=0;i<nodes.length;i++){}
在函数中,this代表触发的元素节点,不能够使用i来定位节点
函数的编写与使用
上述事件触发都是直接为事件赋值函数。事实上函数能够单独定义。然后在事件触发处引用。前边使用的都是匿名函数
不使用匿名函数也能够if推断和正則表達式
正則表達式是对字符串操作非常有效的方法,须要细致研究下。
练习2:对每一个li元素的文本值,假设是以^^開始。那么在点击时取消^^;假设没有^^。那么点击时,加上^^
正則表達式的使用样例:
练习的代码4、节点的属性
节点的属性与属性节点不同。三种节点都有属性。
每种节点都有三个属性:nodeType、nodeName、nodeValue
不同种类的节点的三种属性不同,而id,name,type是详细节点的属性
通过元素节点.的方式获取到的属性,不具有节点的特性。没有这三种属性。仅仅有通过getAttributeNode()的方法获取到的属性节点才具有这三种属性5、创建并增加节点
创建元素节点:var liNode = document.createElement("li"),依据标签名创建元素节点
创建文本节点:var liText = document.createTextNode("str")。依据文本字符串创建文本节点
将文本节点增加为元素节点的子节点:liNode.appendChild(liText);
练习:
需求:在点击submit时,推断是否选择type。若没有选择,给出提示“请选择类型”;
检查文本框中是否有内容(去除前后空格)。若没有,给出提示“请输入内容”;
若检查都通过。在对应的ul下加入li节点<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript"> window.onload = function(){ //1.获取submit相应的节点submitBtn var submitBtn = document.getElementById("submit"); //2.为submitBtn加入onlcick响应函数 //3.在onclick函数的结尾处加入return false。能够取消提交button的默认行为 submitBtn.onclick= function(){ //4.检查是否选择type类型,若没有,给出提示 //4.1选择全部的name="type"的节点集types var types = document.getElementsByName("type"); //4.2遍历types,查看是否有一个type的checked属性存在,就能够说明有一个type元素被选中了: var typeVal=null; for(var i=0;i<types.length;i++){ //用if(节点.属性名)来推断某一个节点是否有该属性 if(types[i].checked){ typeVal=types[i].value; break; } } //4.3若没有不论什么一个type被选中,提示。响应方法结束return false if(typeVal==null){ alert("请选择类型"); return false; } //5.获取name="name"的元素的文本值:通过value属性赋值给nameVal var nameVal=document.getElementsByName("name")[0].value; //6.去除nameVal的前后空格 var reg=/^\s*|^\s*/g; nameVal = nameVal.replace(reg,""); //6.将nameValde 值与""做进行比較,若相等,提示。函数响应结束。返回return false if(nameVal==""){ alert("请输入内容"); return false; } //7.创建li节点 var liNode = document.createElement("li"); //8.创建文本节点liText,利用nameVal var liText = document.createTextNode(nameVal); //9.把liText节点加为li的子节点 liNode.appendChild(liText); //10.把li加为ul的子节点 var ulNode = document.getElementById(typeVal); ulNode.appendChild(liNode); return false; } } </script> </head> <body> <p>你喜欢哪个城市?</p> <ul > <li >北京</li> <li>上海</li> <li>东京</li> <li>首尔</li> </ul> <br/> <br/> <p>你喜欢哪款单机游戏?</p> <ul > <li >红警</li> <li>实况足球</li> <li>极品飞车</li> <li>魔兽</li> </ul> <form action="js-1.html" name="myform"> <input type="radio" name="type" value="city"/>城市 <input type="radio" name="type" value="game"/>游戏 name:<input type="text" name="name" /> <input type="submit" value="Submit" > </form> </body> </html>注意 :1.变量为null的使用
2.怎样推断元素属性存在与否if(元素.属性名)
3.属性注明时,规范做法是checked="checked"6、替换节点
替换节点。使用 父节点.replaceChild(newNode, oldNode)方法,把一个给定父元素里的指定节点替换为还有一个节点。
返回值是一个运行被替换掉的节点的引用指针。即指向oldNode的指针
替换节点。还有移动的效果。被替换的节点从页面显示上消失,替换的节点从原来的位置转移到被替换的位置。
该方法仅仅能单向替换。若实现双向替换,那么须要自定义函数
练习:点击city中的li标签,与game中的对应li标签对换
注意:节点克隆时,事件属性不会克隆(克隆产生的节点不具有事件响应,可是替换节点中事件会保持),需手动复制。
自己加入的属性也不会克隆,自己加入属性的方法就是直接:节点.index=45 或者节点.aa="23",对名称无要求。
关键就在事件的复制。与使用index属性的记录下标,交换节点时,也要交换下标
7、删除节点
删除节点的方法:父节点.removeChild(node),通常在事件响应函数中。使用this.parentNode.removeChild(this)
练习:对每一个li元素节点加入响应函数,通过确认对话框,删除该节点
确认对话框的使用:confirm("确定要删除。。
。
信息吗?")。返回值为布尔值
8、插入节点
前边讲了创建并增加节点。使用的是appendChild(newNode)方法,这种方法是将新建的节点加到最后一个子节点之后。
假设指定插入到某个节点之前。就要使用insertBefore(newNode, existingChild),要指明哪一个子节点
没有insertAfter方法。可是能够依据使用insertAfter方法变相完毕:
function insertAfter(newEl, targetEl) { var parentEl = targetEl.parentNode; if(parentEl.lastChild == targetEl) { parentEl.appendChild(newEl); }else { parentEl.insertBefore(newEl,targetEl.nextSibling); } }nextSibling是属性。返回当前节点的下一节点,假设没有同级的下一节点,返回nullpreviousSibling是返回节点的上一同级节点
9、innerHTML属性
innerHTML属性返回表格中行的開始和结束标签之间的HTML代码比如:
那么显示的是
<th>Firstname</th><th>Lastname</th>