JavaScript(三)-- DOM编程
来源:互联网 发布:pubwin2015数据库账号 编辑:程序博客网 时间:2024/06/08 17:01
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 id="city"><li id="bj" name="BeiJing">北京</li><li>上海</li><li>东京</li><li>首尔</li></ul><br/><br/><p>你喜欢哪款单机游戏?</p><ul id="game"><li id="rl">红警</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>
获取属性节点
读写属性节点,就是读写元素节点的属性,通过元素节点"."的方式获取和读写属性
先获取元素节点,再通过元素节点.得到属性值
<script type="text/javascript">//读写属性节点,属性节点即为某一指定节点元素的属性:通过元素节点.的方式获取属性值和设置属性值window.onload = function(){//1.先获取指定的元素节点var nameNode = document.getElementById("name");//2.再读取指定属性的值alert(nameNode.value);//3.设置指定属性的值nameNode.value="yuchen";}</script></head><body>name:<input type="text" name="username" id="name" value="cqupt"/></body>
获取元素节点的子节点
获取元素节点的子节点,也是先获取到元素节点,
通过元素节点的childNodes获取元素节点的所有子节点,
通过getElementsByTagName()获取指定标签子节点,
通过firstChild和lastChild获取第一个子节点和最后一个子节点。
<script type="text/javascript">window.onload = function(){//1.获取#city节点的所有子节点var cityNode = document.getElementById("city");//2.利用元素节点的childNodes方法获取指定节点元素的所有子节点,但该方法不实用alert(cityNode.childNodes.length);//输出为9,对于ul中,有文本节点和li元素节点//3.获取#city节点的所有li子节点var lis = cityNode.getElementsByTagName("li");alert(lis.length);//4.获取指定节点的第一个子节点和最后一个子节点alert(cityNode.firstChild);alert(cityNode.lastChild);}</script>
获取文本节点
文本节点一定是元素节点的子节点,先通过获取元素节点,再定位到文本节点,通过文本节点的nodeValue属性读写文本值。
<script type="text/javascript">//文本节点一定是元素节点的子节点window.onload = function(){//1.获取元素节点var bjNode = document.getElementById("bj");//2.通过firstChild定位到文本节点var bjTextNode = bjNode.firstChild;//3.通过文本节点的nodeValue属性读取文本值alert(bjTextNode.nodeValue);//4.通过文本节点的nodeValue属性改变文本值bjTextNode.nodeValue = "重庆";//“重庆”替换掉“北京”}</script>
3、两个练习
for循环和函数中的this
练习1:点击所有li标签元素时,弹出该元素节点的文本值
for循环,变量都是var定义的for(var i=0;i<nodes.length;i++){}
在函数中,this代表触发的元素节点,不可以使用i来定位节点
<script type="text/javascript">window.onload = function(){//1.获取所有标签li的元素集合var liNodes = document.getElementsByTagName("li");//2.通过for循环,获取元素集合中的每个元素节点,for(var i=0;i<liNodes.length;i++){//3.为元素节点的onclick事件赋值函数liNodes[i].onclick = function(){//4.函数中this代表当前触发的元素节点,firstChild方法获取元素节点的文本节点var liTextNode = this.firstChild;//5.获取文本节点的值alert(liTextNode.nodeValue);//不可以使用i来定位元素,因为事件触发是发生在,赋值函数完成后,//触发事件时,i的值已经变为liNodes.length,而此时liNodes[i]不执行任何节点//var liTextNode = liNodes[i].firstChild}}}</script>
函数的编写与使用
上述事件触发都是直接为事件赋值函数,其实函数可以单独定义,然后在事件触发处引用,前边使用的都是匿名函数
<script type="text/javascript">window.onload = function(){var but = document.getElementById("but");//使用函数的引用,如果在引用后加(),也就是hello(),那么文档加载时就会执行函数,把函数执行的结果赋值给事件but.onclick = hello();//单独定义函数,然后在事件触发出使用函数的引用function hello(){alert("helloworld")}}</script>不使用匿名函数也可以
<script type="text/javascript">window.onload = function (){var but = document.getElementById("but");//不使用匿名函数也可以,可以为韩式指定名字,一般直接为事件赋值函数时,使用匿名函数but.onclick = function hello(){alert("helloworld")}}</script>
if判断和正则表达式
正则表达式是对字符串操作很有效的方法,需要仔细研究下。
练习2:对每个li元素的文本值,如果是以^^开始,那么在点击时取消^^;如果没有^^,那么点击时,加上^^
正则表达式的使用例子:
<script type="text/javascript">window.onload = function (){var str1="^^abc";var str2="abc";var reg = /^\^{2}/g;//正则表达式//利用正则表达式判读字符串中是否含有^^alert(reg.test(str1));alert(reg.test(str2));//利用正则表达式,将字符串中的^^替换为""alert(str1.replace(reg,""));}</script>练习的代码
<script type="text/javascript">window.onload = function(){var liNodes = document.getElementsByTagName("li");for(var i=0;i<liNodes.length;i++){liNodes[i].onclick = function(){var reg = /^\^{2}/g;//正则表达式var val = this.firstChild.nodeValue;if(reg.test(val)){val = val.replace(reg,"");}else{val= "^^"+val;}//记得最后要把文本值给替换this.firstChild.nodeValue = val;}}}</script>
4、节点的属性
节点的属性与属性节点不同,三种节点都有属性。
每种节点都有三个属性:nodeType、nodeName、nodeValue
不同种类的节点的三种属性不同,而id,name,type是具体节点的属性
<script type="text/javascript">window.onload = function(){var bjNode = document.getElementById("bj");alert(bjNode.nodeType);//元素节点 ,值为1alert(bjNode.nodeName);//节点标签名:LIalert(bjNode.nodeValue);//元素节点没有nodeValue值,为:null//<input type="text" name="username" id="name" value="cqupt"/>var nameAttr = document.getElementById("name").getAttributeNode("name");alert(nameAttr.nodeType);//属性节点 ,值为2alert(nameAttr.nodeName);//节点属性名:namealert(nameAttr.nodeValue);//属性值:usernamevar bjTextNode = document.getElementById("bj").firstChild;alert(bjTextNode.nodeType);//文本节点 ,值为3alert(bjTextNode.nodeName);//节点名:#textalert(bjTextNode.nodeValue);//值为文本节点本身的值:北京//nodeType 和 nodeName是只读的//nodeValue是可以改变的}</script>通过元素节点.的方式获取到的属性,不具有节点的特性,没有这三种属性,只有通过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对应的节点submitBtnvar submitBtn = document.getElementById("submit");//2.为submitBtn添加onlcick响应函数//3.在onclick函数的结尾处添加return false,可以取消提交按钮的默认行为submitBtn.onclick= function(){//4.检查是否选择type类型,若没有,给出提示//4.1选择所有的name="type"的节点集typesvar 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 falseif(typeVal==null){alert("请选择类型");return false;}//5.获取name="name"的元素的文本值:通过value属性赋值给nameValvar nameVal=document.getElementsByName("name")[0].value;//6.去除nameVal的前后空格var reg=/^\s*|^\s*/g;nameVal = nameVal.replace(reg,"");//6.将nameValde 值与""做进行比较,若相等,提示,函数响应结束,返回return falseif(nameVal==""){alert("请输入内容");return false;}//7.创建li节点var liNode = document.createElement("li");//8.创建文本节点liText,利用nameValvar 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 id="city"><li id="bj">北京</li><li>上海</li><li>东京</li><li>首尔</li></ul><br/><br/><p>你喜欢哪款单机游戏?</p><ul id="game"><li id="rl">红警</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" id="submit"></form></body></html>注意 :
1.变量为null的使用
2.如何判断元素属性存在与否if(元素.属性名)
3.属性注明时,规范做法是checked="checked"6、替换节点
替换节点,使用 父节点.replaceChild(newNode, oldNode)方法,把一个给定父元素里的指定节点替换为另一个节点;
返回值是一个执行被替换掉的节点的引用指针,即指向oldNode的指针
替换节点,还有移动的效果,被替换的节点从页面显示上消失,替换的节点从原来的位置转移到被替换的位置。
该方法只能单向替换,若实现双向替换,那么需要自己定义函数
<script type="text/javascript">window.onload = function(){//替换节点:父类节点.replaceChild(newNode, oldNode)//克隆节点:节点.cloneNode(true)深度克隆为true(将子节点一起克隆)//节点替换具有移动的效果,被替换的节点显示消失(但节点还存在),替换节点从原位置转移到替换节点处var bjNode = document.getElementById("bj");var rlNode = document.getElementById("rl");replaceEach(bjNode,rlNode);}//函数定义可写在其他函数的外部,也可以写在内部//注意:定义函数时,参数不能写var类型,直接参数名function replaceEach(aNode,bNode){var aParent = aNode.parentNode;var bParent = bNode.parentNode;//克隆其中一个节点,用克隆节点去替换另一节点var clone = aNode.cloneNode(true);//替换过程if(aParent && bParent){//replaceChild函数的返回值是一个指向被替换的节点的引用指针var node = bParent.replaceChild(clone,bNode);alert(node.firstChild.nodeValue);//红警aParent.replaceChild(bNode,aNode);}}</script>
练习:点击city中的li标签,与game中的相应li标签对换
注意:节点克隆时,事件属性不会克隆(克隆产生的节点不具有事件响应,但是替换节点中事件会保持),需手动复制。
自己添加的属性也不会克隆,自己添加属性的方法就是直接:节点.index=45 或者节点.aa="23",对名称无要求。
关键就在事件的复制,与使用index属性的记录下标,交换节点时,也要交换下标<script type="text/javascript">window.onload = function(){//1.为所有的li标签添加onclick事件,赋值函数var liNodes = document.getElementsByTagName("li");for(var i=0;i<liNodes.length;i++){//为节点添加index属性,用以记录下标值liNodes[i].index=i;liNodes[i].onclick = function(){var targetIndex = (this.index+4)%8;//alert(targetIndex);//先交换index属性值var tempIndex = this.index;this.index = liNodes[targetIndex].index;liNodes[targetIndex].index = tempIndex;replaceEach(this,liNodes[targetIndex]);}}}function replaceEach(aNode,bNode){var aParent = aNode.parentNode;var bParent = bNode.parentNode;if(aParent && bParent){var clone = aNode.cloneNode(true);//事件onclick需要手动克隆clone.onclick = aNode.onclick;bParent.replaceChild(clone,bNode);aParent.replaceChild(bNode,aNode);}}</script>
7、删除节点
删除节点的方法:父节点.removeChild(node),通常在事件响应函数中,使用this.parentNode.removeChild(this)
练习:对每个li元素节点添加响应函数,通过确认对话框,删除该节点
确认对话框的使用:confirm("确定要删除。。。信息吗?"),返回值为布尔值
<script type="text/javascript">window.onload = function(){//删除节点:父节点.removeChild(node)var liNodes = document.getElementsByTagName("li");for(var i=0;i<liNodes.length;i++){liNodes[i].onclick = function(){//confirm(""):确认对话框,返回值为布尔值var flag = confirm("确定要删除:"+this.firstChild.nodeValue+" 信息吗?");if(flag){this.parentNode.removeChild(this);}}}}</script>
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是属性,返回当前节点的下一节点,如果没有同级的下一节点,返回null
previousSibling是返回节点的上一同级节点
9、innerHTML属性
innerHTML属性返回表格中行的开始和结束标签之间的HTML代码例如:
<table border="1"><tr id="tr1"><th>Firstname</th><th>Lastname</th></tr><tr id="tr2"><td>Peter</td><td>Griffin</td></tr></table>那么
alert(document.getElementById("tr1").innerHTML);显示的是
<th>Firstname</th>
<th>Lastname</th>
- JavaScript(三)-- DOM编程
- Javascript Dom编程艺术读书笔记(三)
- JavaScript DOM编程艺术 学习笔记(三)DOM
- 读书小记——Javascript DOM编程艺术(三)
- 高性能Javascript【三】DOM编程
- javascript之Dom编程艺术三
- JavaScript DOM(三)-DOM事件
- javaScript-DOM操作(三)
- JavaScript DOM 事件(三)
- JavaScript(含DOM编程)
- javascript DOM 编程(读书笔记)
- DOM编程练习(三)
- DOM编程-事件(三)
- 【JavaScript】JavaScript DOM 编程
- 【JavaScript】JavaScript DOM 编程
- 【JavaScript DOM编程艺术】- DOM
- javascript dom 学习笔记(三),ajax
- JavaScript DOM 三
- jQuery-UI 拖动Div交换位置
- leetcode笔记--Longest Common Prefix
- 解析Xml的理解
- 数据结构课程设计报告-职工信息管理系统
- 如何使用 Java8 实现观察者模式?(上)
- JavaScript(三)-- DOM编程
- 华为P8解锁问题:waiting for device解决方法(亲测成功)
- oracle 恢复误删除数据
- ICPCCamp 2016 Day 3 - Grand Prix of China(Random Arithmetic-dp)
- Java开发环境搭建
- poj 1679 The Unique MST(次小生成树)
- 1097. Deduplication on a Linked List (25)
- perl HTML::TreeBuilder::XPath
- [从头学数学] 第106节 整理与复习--数学思考