版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
十四、DOM模型<html><head><metahttp_equiv="conten_type"content="text/html;charset=gb2312"/></head><body><h2><ahref="#isaac">标题1</a></h2><p>段落1</p><ulid="myUI"><li>JavaScript</li><li>DOM</li><li>CSS</li></ul></body></html>2288一个网页的基本结构为树形结构,<html>标记位于顶端,称为DOM的根节点,而在根节点下面有两个分支,分别为<head>和<body>分支。它们处于同级的兄弟关系,相当于“同级目录”,称为同级节点。其它标记也可以按这种方式分析。htmlheadbodymetaptitleulh2alilili2289html文件是节点构成的集合。在DOM中有3种节点,分别为元素节点、文本节点和属性节点。1、元素节点可以说整个DOM模型都是由元素节点(elementnode)构成的。从上图中可以看出,<html>、<body>、<meta>、<h2>、<p>、<li>等都是元素节点,各种标记便是这些元素节点的名称。在元素节点中还可以包含其它元素,即在标记中可以套其它标记,例如,在上例中<ul>标记里套了<li>标记。2、文本节点在HTML文档中只用标记搭建框架是不够的,还2290要向用户显示页面内容,例如在<h2>标记中要显示文本“标题1”,项目列表<li>标记中还要显示Javascript、DOM、CSS等。这些具体的文本在DOM模型中称之为文本节点(textnode).在XHTML文档里,文本节点总是包含在元素节点里,但是并不是所有元素节点都包含文件内容,例如<ul>元素里并没有直接显示任何文本内容,只包含了一些元素节点,例如<li>,并在<li>元素中显示文本内容。2、属性节点(attributenode)在标记元素中,或多或少地使用了一些标记属性,例如:<atitle="CSS"href="">网易主页</a>2291在以上代码中,title="CSS"和href="分别是两个属性节点。由于标记属性总是放在标记中,因此属性节点总是包含在元素节点之中。2292a元素节点title="CSS"href="网易主页属性节点属性节点文本节点各节点之间的关系图十五、DOM应用DOM模型中的节点主要用于处理HTML网页,即用DOM来操作页面文档。对于每一个DOM节点node来讲,有一系列的属性和方法函数可以使用,在应用节点以前要了解节点的常用属性和方法函数:属性/方法名
类型/返回类型
说明nodeNameString
节点名称,根据节
点的类型而定义2293nodeValueString
节点的值,同样根据节点的类型而定义nodeTypeNumber
节点类型,常量值之一firstChildNode
指向childNodes列表中
的第一个节点lastChildNode
指向childNodes列表中
的最后一个节点childNotesNodeList
所有子节点的列表,方法item(i)可以访问第i+1个节点parentNodeNode
指向节点的父节点,如果
已经是根节点,则返回null2294previousSiblingNode
指向前一个兄弟节点,如果该节点已经是第一个节点,则返回nullnextSiblingNode
指向后一个兄弟节点,如果该节点已经是最后一个节点,则返回nullhaschildNodes()Boolean
当childNodes包含一个或者多个节点时,返回true.attributesNameNodeMap包含一个元素特性的Attr对象,仅用于元素节点。appendChild(node)node
将node节点添加到childNodes的末尾removeChild(node)node
从childNodes节点中删除node节点。2295replaceChild(newnode)node
将childNodes节点中lodnode节点替换成newnode节点。insertBefore(newnode,refnode)node
在childNodes节点中的refnode节点之前插入newnode节点。1、访问节点DOM提供了两个访问节点的常用方法函数:getElementsByTagName()getElementsById()getElementsByTagName()函数用来返回某个相同标记元素的NodeList,例如用此函数返回某个HTML文档中的<li>标记元素的列表:2296varoLi=document.getElementsByTagName("li");特别指出,只有当文档加载完毕以后才能正确分析DOM结构,那么以下两个取元素的方法函数才会有效:getElementsByTagName()getElementsById()h249.html文件内容2297<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>getElementsByTagName()</title><scriptlanguage="javascript">2298functionsearchDOM(){ //放在函数内,页面加载完成后才用<body>的onload加载
varoLi=document.getElementsByTagName("li"); //输出长度、标签名称以及某项的文本节点值
alert(oLi.length+""+oLi[0].tagName+""+oLi[3].childNodes[0].nodeValue); varoUl=document.getElementsByTagName("ul"); varoLi2=oUl[1].getElementsByTagName("li"); alert(oLi2.length+""+oLi2[0].tagName+""+oLi2[1].childNodes[0].nodeValue);}</script></head>2299<bodyonload="searchDOM()"> <ul>客户端语言 <li>HTML</li> <li>JavaScript</li> <li>CSS</li> </ul><ul>服务器端语言 <li></li> <li>JSP</li> <li>PHP</li></ul></body></html>2300在上例中,
有2个ul标记。而每个ul标记中分别有3个li标记,总共有6个li标记。提示:varoLi=document.getElementsByTagName("li");此句代码的意思,把文档中所有的li标记提取出来形成一个节点数组,放在oLi变量中。所以oLi变量是个数组变量,在后面的代码中用数组的方法来写代码就行了。在文档中一共有6个li标记,那么这个数组长度为6,元素编号从0~5.varoUl=document.getElementsByTagName("ul");由于ul在文档中只有二个,所以oUl变量只有两个元素,元素编号为0~1.2301id号或者id名在HTML文档中是惟一的。id可以在CSS进行定义或者添加其属性,也可以不在CSS中定义或者添加属性,可以直接在标记中指定id名称,例如:<liid="cssLi">CSS</li>这个"cssLi"名称就是<li>标记的id名称,可能id号并没有在CSS中定义它的属性,但一样可以在<li>标记里使用,指定此<li>标记的名称为cssLi。h250.html文件内容2302<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>getElementById()</title><scriptlanguage="javascript">functionsearchDOM(){ varoLi=document.getElementById("cssLi"); //输出标签名称以及文本节点值 alert(oLi.tagName+""+oLi.childNodes[0].nodeValue);}</script></head>2303<bodyonload="searchDOM()"> <ul>客户端语言 <li>HTML</li> <li>JavaScript</li> <liid="cssLi">CSS</li> </ul><ul>服务器端语言 <li></li> <li>JSP</li> <li>PHP</li></ul></body></html>2304提示:varoLi=document.getElementById("cssLi");由于oLi变量不是数组,所以不能使用数组长度属性length或者数组下标,例如以下使用方式是错误的:oLi.lengthoLi[0].childNodes[0].nodeValue注意:在IE浏览器中,如果id名与某个标记同名时,那个标记元素的值会被返回。这是非常严重的bug,也是开发网页者要注意的地方。因此,在开发网页时要避免id名与其它元素同名。23052、检查节点类型通过节点的nodeType属性可以检测出节点的类型。
该属性返回一个整数值,一共有12个值,其中1、2、3分别代表元素节点、属性节点和文本节点,其它值基本上用不上。例如:alert(document.nodeType);3、利用父、子、兄关系查找节点父、子、兄关系是DOM模型中节点之间的最重要的三种关系。2306在获取某个节点之后,可通过父子关系,并利用haChildNodes()方法函数和childNodes属性获取该节点所包含的所有子节点。复习:haschildNodes()Boolean
当childNodes包含一个或者多个节点时,返回true.childNotesNodeList
所有子节点的列表,是数组,方法item(i)可以访问第i+1个节点h251.html文件内容2307<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>childNodes</title><scriptlanguage="javascript">functionmyDOMInspector(){varoUl=document.getElementById("myList"); //获取<ul>标记varDOMString="";2308if(oUl.hasChildNodes()){ //判断是否有子节点
varoCh=oUl.childNodes; for(vari=0;i<oCh.length;i++) //逐一查找
DOMString+=oCh[i].nodeName+"\n"; } alert(DOMString);}</script></head>2309<bodyonload="myDOMInspector()"> <ulid="myList"> <li>糖醋排骨</li> <li>圆笼粉蒸肉</li> <li>泡菜鱼</li><li>板栗烧鸡</li><li>麻婆豆腐</li> </ul></body></html>23102311解释:在上例中,提醒框里显示的内容有#text。这是由于在ul无序列表中有空格存在直接导致了显示#text。可以做个实验,可以把ul无序列表的代码修改如下:<ulid="myList"><li>糖醋排骨</li><li>圆笼粉蒸肉</li><li>泡菜鱼</li><li>板栗烧鸡</li><li>麻婆豆腐</li></ul>显示结果如下:2312通过父节点可以轻松地寻找到子节点,同样利用parentNode属性可以获取一个节点的父节点。复习:parentNodeNode指向节点的父节点,如果已经是根节点,则返回nullh252.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html>2313<head><title>parentNode</title><scriptlanguage="javascript">functionmyDOMInspector(){varmyItem=document.getElementById("myDearFood"); alert(myItem.parentNode.tagName);}</script></head>2314<bodyonload="myDOMInspector()"> <ul> <li>糖醋排骨</li> <li>圆笼粉蒸肉</li> <li>泡菜鱼</li> <liid="myDearFood">板栗烧鸡</li> <li>麻婆豆腐</li> </ul></body></html>2315通过parentNode属性可以成功取得父节点,同时任何节点都有此属性,这样可以由子节点一直往上搜索,直到body节点为止。h253.html文件内容2316<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>parentNode</title><scriptlanguage="javascript">2317functionmyDOMInspector(){ varmyItem=document.getElementById("myDearFood"); varparentElm=myItem.parentNode; while(parentElm.className!="colorful"&&parentElm!=document.body) parentElm=parentElm.parentNode; //一路往上找
alert(parentElm.tagName);}</script></head>2318<bodyonload="myDOMInspector()"><divclass="colorful"><ul> <li>糖醋排骨</li> <li>圆笼粉蒸肉</li> <li>泡菜鱼</li> <liid="myDearFood">板栗烧鸡</li> <li>麻婆豆腐</li> </ul></div></body></html>2319提示:从while循环语句可以看出,节点最多寻找到<divclass="colorful">位置,然后不满足while循环条件跳出循环。所以最后的父节点的位置应该是<div>标记。2320父子关系是上层与下层之间的关系,而兄弟之间的关系是平级关系,可以用以下方法或者属性决定:previousSiblingNode指向前一个兄弟节点,如果该节点已经是第一个节点,则返回nullnextSiblingNode指向后一个兄弟节点,如果该节点已经是最后一个节点,则返回nullh254.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""">2321<html><head><title>Siblings</title><scriptlanguage="javascript">functionmyDOMInspector(){varmyItem=document.getElementById("myDearFood"); //访问兄弟节点
varnextListItem=myItem.nextSibling; varpreListItem=myItem.previousSibling;alert(nextListItem.tagName+""+preListItem.tagName);}2322</script></head><bodyonload="myDOMInspector()"><ul> <li>糖醋排骨</li> <li>圆笼粉蒸肉</li> <li>泡菜鱼</li> <liid="myDearFood">板栗烧鸡</li> <li>麻婆豆腐</li> </ul></body></html>2323在IE6.0浏览器上,此例结果正常,如下图所示:但在Chrome浏览器上显示不正常,如下图所示:2324这是怎么回事呢?看起来代码无懈可击,可是就是出现了问题。这是由于在IE9.0浏览器和Chrome浏览器把代码中众多的空格当成了文本节点,结果导致了错误。所以,以上代码只适合于低版本的IE浏览器。为了上例中代码的兼容性,可用nodeType属性对节点类型进行判断,这样访问相邻的兄弟节点就没有问题了。2325h255.html文件内容说明:节点对象.nodeType=1,表示此节点对象为元素节点<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>Siblings</title>2326<scriptlanguage="javascript">functionnextSib(node){ vartempLast=node.parentNode.lastChild;//判断是否是最后一个节点,如果是则返回null if(node==tempLast) returnnull; vartempObj=node.nextSibling;//逐一搜索后面的兄弟节点,直到发现元素节点为止
while(tempObj.nodeType!=1&&tempObj.nextSibling!=null) tempObj=tempObj.nextSibling;2327//三目运算符,如果是元素节点则返回节点本身,否则返回null。元素节点时tempObj.nodeType==1return(tempObj.nodeType==1)?tempObj:null;}2328functionprevSib(node){ vartempFirst=node.parentNode.firstChild;//判断是否是第一个节点,如果是则返回null if(node==tempFirst) returnnull; vartempObj=node.previousSibling;//逐一搜索前面的兄弟节点,直到发现元素节点为止
while(tempObj.nodeType!=1&&tempObj.previousSibling!=null) tempObj=tempObj.previousSibling;return(tempObj.nodeType==1)?tempObj:null;}2329functionmyDOMInspector(){varmyItem=document.getElementById("myDearFood"); //获取后一个元素兄弟节点
varnextListItem=nextSib(myItem); //获取前一个元素兄弟节点
varpreListItem=prevSib(myItem); alert("后一项:"+((nextListItem!=null)?nextListItem.firstChild.nodeValue:null)+"前一项:"+((preListItem!=null)?preListItem.firstChild.nodeValue:null));}</script>2330</head><bodyonload="myDOMInspector()"><ul> <li>糖醋排骨</li> <li>圆笼粉蒸肉</li> <li>泡菜鱼</li> <liid="myDearFood">板栗烧鸡</li> <li>麻婆豆腐</li> </ul></body></html>2331在上例中,使用以下循环语句判断当前节点不是元素节点并且不是第一个节点,则继续寻找前一个节点。如果当前节点是元素节点和第一个节点,则循环条件不成立退出循环:while(tempObj.nodeType!=1&&tempObj.previousSibling!=null) tempObj=tempObj.previousSibling;2332寻找下一个节点的循环语句原理一样:while(tempObj.nodeType!=1&&tempObj.nextSibling!=null) tempObj=tempObj.nextSibling;4、设置节点属性寻找到节点以后可以查询节点属性,也可以设置节点属性,主要用以下两个方法函数来完成:getAttribute(属性)获得节点属性setAttribute(属性,参数)设置节点属性此两个方法函数只能被节点调用,不能被document对象调用。2333h255.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><title>getAttribute()和setAttribute()</title><scriptlanguage="javascript">2334functionmyDOMInspector(){ //获取图片,取第一个img标记的内容varmyImg=document.getElementsByTagName("img")[0]; //获取图片title属性
alert(myImg.getAttribute("title"));}functionchangePic(){ //获取图片varmyImg=document.getElementsByTagName("img")[0]; //设置图片src和title属性
myImg.setAttribute("src","02.jpg"); myImg.setAttribute("title","紫荆公寓");2335}</script></head><bodyonload="myDOMInspector()"><imgsrc="01.jpg"title="情人坡"onclick="changePic()"/></body></html>233601.jpg02.jpg2337单击5、创建和添加节点在DOM中创建节点比较规范。createElement()创建一个元素节点createTextNode()创建一个文本节点createDocumentFragment()创建一个文档碎片节点父节点.appendchild(子节点),把子节点添加到父节点中子节点列表的最后面。h256.html文件内容2338<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>创建新节点</title><scriptlanguage="javascript">2339functioncreateP(){ varoP=document.createElement("p");//创建一个P节点放在oP变量中 varoText=document.createTextNode("这是一段感人的故事");//用字符串"这是一段感人的故事"创建一个文件节点,并把此文本节点放在oText变量中 oP.appendChild(oText);//在P标记的元素节点oP中添加文件节点oText document.body.appendChild(oP);//有文档的body标记中添加P标记的oP节点}2340</script></head><bodyonload="createP()"><p>事先写一行文字在这里,测试appendChild()方法的添加位置</p></body></html>23416、删除节点删除节点是通过父节点的removeChild()方法函数来完成的。通常的方法是先寻找到欲删除的节点,然后再利用parentNode属性寻找到其父节点,再用此removeChild()方法函数把此子节点删除。h257.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""">2342<html><head><title>删除节点</title><scriptlanguage="javascript">functiondeleteP(){ varoP=document.getElementsByTagName("p")[0]; varfarNane=oP.parentNode; farName.removeChild(oP); //oP.parentNode.removeChild(oP); //删除节点}2343</script></head><bodyonload="deleteP()"><p>这行文字你看不到</p></body></html>23447、替换节点用replaceChild()的方法函数来替换节点。此函数同样是用父节点来操作子节点的,即:父节点.replaceChild(新子节点,旧子节点)功能:用新子节点来替换旧子节点。h258.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head>2345<title>替换节点</title><scriptlanguage="javascript">functionreplaceP(){ varoOldP=document.getElementsByTagName("p")[0]; varoNewP=document.createElement("p"); //新建节点
varoText=document.createTextNode("这是一个感人肺腑的故事"); oNewP.appendChild(oText);
oOldP.parentNode.replaceChild(oNewP,oOldP);//替换节点}2346</script></head><bodyonload="replaceP()"><p>这行文字被替换了</p></body></html>23478、在特定节点前插入节点appendchild()方法函数只能把节点添加到父节点中子节点列表(childNodes)的最后面。然而有时需要把某节点插入到某个子节点的前面,这时要使用以下方法函数:父节点.insertBefore(新节点,目标节点);功能:把新节点插入到目标节点以前。h259.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""">2348<html><head><title>插入节点</title><scriptlanguage="javascript">functioninsertP(){
varoOldP=document.getElementsByTagName("p")[0]; varoNewP=document.createElement("p"); //新建节点
varoText=document.createTextNode("这是一个感人肺腑的故事"); oNewP.appendChild(oText);//此时的 oNewP节点还没有上屏幕2349oOldP.parentNode.insertBefore(oNewP,oOldP);//插入节点,在原来的P节点前插入新的P节点}</script></head><bodyonload="insertP()"><p>插入到这行文字之前</p></body></html>2350当节点添加到页面中时通常页面会更新,马上显示出页面的变化。当添加的节点数目多时页面执行的效率就会降低。解决的办法就是创建一个文档碎片,先把新节点添加到文档碎片里,然后再一次性地添加到实际的网页中。建立文档碎片对象:varoFragment=document.createDocumentFragment();h260.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html>2351<head><title>文档碎片</title><styletype="text/css"><!--p{ padding:2px; margin:0px;}--></style><scriptlanguage="javascript">2352functioninsertPs(){ varaColors=["red","green","blue","magenta","yellow","chocolate","black","aquamarine","lime","fuchsia","brass","azure","brown","bronze","deeppink","aliceblue","gray","copper","coral","feldspar","orange","orchid","pink","plum","quartz","purple"];varoFragment=document.createDocumentFragment(); //创建文档碎片
for(vari=0;i<aColors.length;i++){ varoP=document.createElement("p");varoText=document.createTextNode(aColors[i]); 2353oP.appendChild(oText); oFragment.appendChild(oP); //将节点先添加到碎片中
} document.body.appendChild(oFragment); //最后一次性添加到页面}</script></head><bodyonload="insertPs()"></body></html>2354分析:1)变量aColors是个数组,把要显示的内容用数组的方式存储在此变量中。2)建立文档碎片对象oFragment。3)用数组aColors的循环语句,先创建一个P标记节点oP,然后再用aColors数组中的每一个元素建立一个文本节点oText,然后再把每个文本节点放在oP节点中,最后把每个oP节点放在文档碎片对象oFragment中。4)最后把文档碎片对象oFragment2355用以下语句添加到页面上:document.body.appendChild(oFragment);9、在特定节点后插入节点复习:父节点.insertBefore(新节点,目标节点)解决了在某节点之前插入新节点。如果想在某节点之后添加新节点,是否有以下方法函数呢?父节点.insertAfter(新节点,目标节点)其实情况是没有些方法函数,但我们可以自己定义一个在某节点后面插入一个新节点的函数。2356functioninsertAfter(newElement,targetElement){ varoParent=targetElement.parentNode;//首先找到目标元素的父元素
if(oParent.lastChild==targetElement) //如果目标元素已经是最后一个子元素了
oParent.appendChild(newElement);//则直接用appendChild()加到子元素列表的最后
else //否则用insertBefore()插入到目标元素的下一个兄弟元素之前
oParent.insertBefore(newElement,targetElement.nextSibling);}2357以后可以把以上自定义函数添加到需要的地方。h261.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>insertAfter()方法</title><scriptlanguage="javascript">2358functioninsertAfter(newElement,targetElement){ varoParent=targetElement.parentNode; //首先找到目标元素的父元素
if(oParent.lastChild==targetElement) //如果目标元素已经是最后一个子元素了
oParent.appendChild(newElement);//则直接用appendChild()加到子元素列表的最后
else //否则用insertBefore()插入到目标元素的下一个兄弟元素之前
oParent.insertBefore(newElement,targetElement.nextSibling);}2359functioninsertP(){ varoOldP=document.getElementById("myTarget"); varoNewP=document.createElement("p"); //新建节点
varoText=document.createTextNode("这是一个感人肺腑的故事"); oNewP.appendChild(oText); insertAfter(oNewP,oOldP); //插入节点}</script></head>2360<bodyonload="insertP()"> <pid="myTarget">插入到这行文字之后</p> <p>也就是插入到这行文字之前,但这行没有id,也可能不存在</p></body></html>2361十六、使用非标准DOMinnerHTML属性除前面介绍了一系列标准DOM方法以外,innerHTML属性由于使用方便,也得到了主流浏览器的支持。此属性表示某个标记之间的所有内容,包括代码本身。此属性可以读取,也可以设置。需要说明的是,innerHTML属性并不是W3CDOM的标准组成部分。虽然在插入大段的HTML内容时可以又快又简捷地完成任务,但它可以直接显示标记里或者对象里的内容,也可以被替换内容。2362h262.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>innerHTML</title><scriptlanguage="javascript">functionmyDOMInnerHTML(){varmyDiv=document.getElementById("myTest"); 2363alert(myDiv.innerHTML); //直接显示innerHTML的内容
//修改innerHTML,可直接添加代码
myDiv.innerHTML="<imgsrc='01.jpg'title='情人坡'>";}</script></head><bodyonload="myDOMInnerHTML()"><divid="myTest"> <span>图库</span> <p>这是一行用于测试的文字</p>2364</div></body></html>2365十七、DOM与CSS1、页面的三位一体:html或者xhtml的标记负责创建网页的结构,即显示内容和显示顺序由各标记来决定。而显示的效果则由CSS来一确定,我们把显示效果叫表现。而行为主要是事件发生时的响应方式,由JS(JavaScript)来负责。所谓三位一体,就是结构、表现和行为为一体。其实在HTML中结构、表现和行为也有重叠的地方。在CSS里也有行为,例如伪选择器hover等。23662、className属性DOM都是与结构层打交道的,例如查找节点、添加节点等。而DOM还有一个非常实用的className属性,可以修改某个节点的CSS类别。h263.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>className属性</title>2367<styletype="text/css">.myUL1{ color:#0000FF; font-family:Arial; font-weight:bold;}.myUL2{ color:#FF0000; font-family:Georgia,"TimesNewRoman",Times,serif;}2368</style><scriptlanguage="javascript">functioncheck(){ varoMy=document.getElementsByTagName("ul")[0]; oMy.className="myUL2"; //修改CSS类}</script></head>2369<body> <ulonclick="check()"class="myUL1"> <li>HTML</li> <li>JavaScript</li> <li>CSS</li> </ul></body></html>效果提示:刚开始时显示红色字符,单周网页上的文字显示字符颜色转换为红色。2370文字原来ul标记引用了myUL1类选择器,单击文字后,调用了check()函数,结果用className属性修改了ul标记的className,自然原来引用的myUL1类选择器失效,新引用了myUL2类选择器,结果修改了ul标记的类选择器,字符显示红色。2371单击文字上例由于myUL1类选择器和myUL2类选择器都是更改字符颜色,属于同类属性修改。在这种情况下要用替换方式更改,即要用赋值语句更改旧类别选择器为新类别选择器,即:oMy.className="myUL2";如果遇到新类别选择器的新属性与旧的类别选择器的属性不同,则最好采用添加新属性的方式进行,即:oMy.className+="myUL2";此句代码相当于:<ulclass="myUL1myUL2">2372h264.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>追加CSS类别</title><styletype="text/css">.myUL1{ color:#0000FF; font-family:Arial; 2373font-weight:bold;}.myUL2{ text-decoration:underline;}</style><scriptlanguage="javascript">functioncheck(){ varoMy=document.getElementsByTagName("ul")[0]; oMy.className+="myUL2"; //追加CSS类2374}</script></head><body> <ulonclick="check()"class="myUL1"> <li>HTML</li> <li>JavaScript</li> <li>CSS</li> </ul></body></html>23752376单击文字第二部分JavaScript、CSS、DOM高级篇2377一、事件流eventflow有了JS,就可以让用户不仅可以观看网页上的内容,还可以与浏览的画面进行交互。浏览器的事情模型分为两种:捕获型事件(eventcapturing)和冒泡事件(dubbedbubbling)IE浏览器不支持捕获事件,只支持冒泡事件。冒泡事件:当鼠标单击了某个低级元素,则此事情将逐层返回到它的上击元素,最后到达document元素位置。h265.html文件内容2378<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>冒泡型事件</title><scriptlanguage="javascript">functionadd(sText){ varoDiv=document.getElementById("display"); oDiv.innerHTML+=sText;2379 //输出点击顺序}</script></head><bodyonclick="add('body<br>');"> <divonclick="add('div<br>');"> <ponclick="add('p<br>');">ClickMe</p> </div> <divid="display"></div></body></html>2380选定P标记,然后一级级向上冒泡触发其它标记里的事件。23812382其实,Chrome浏览器也有冒泡事件流,如下图所示:结果实验证明,其它浏览器同样有冒泡事件流。例如Safiri浏览器,Opera浏览器,Firefox浏览器,QQ浏览器和360浏览器等。捕获事件从document开始向最后一级元素传递鼠标单击事件流。当事件流通过各个元素时各元素都会接收到鼠标事件。捕获事件一般不用,IE浏览器也不支持。23832384二、事件监听在AS3.0中,有监听函数addEventListener(),专门监听事件用的函数。而在JS中,添加onclick函数就可以随时监听事件发生没有,然后当事件产生以后直接调用onclick=后面的响应函数,一般的表达式:监听函数onclick="函数函数()"这种监听方式在主流浏览器里都能使用,包括IE9.0浏览器也能使用。但在低版本的IE浏览器里有自己的监听函数和监听调用函数的方式:[object].attachEvent("event_hander","fnHandler");[object].detachEvent("event_hander","fnHandler");其中,event_hander表示事件名称,如onclick,onload,onmouseover等,而fnHandler表示事件响应函数名称。IE浏览器的监听和调用响应函数的方式与flash中在AS3.0里使用监听函数和调用响应函数的方式完全一样,只是使用的监听函数名有区别。h266.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""">2385<html><head><title>监听函数</title><scriptlanguage="javascript">window.onload=function(){ varoP=document.getElementById("myP"); //找到对象
oP.onclick=function(){ //设置事件监听函数
alert('我被点击了'); }}2386</script></head><body> <div> <pid="myP">ClickMe</p> </div></body></html>注释:window.onload=function(){。。表示当文档加载完成以后,就执行=号右边的函数。2387在标记里使用onclick=时,如果=号右边是函数名,则一般要添加"号,而如果是function(){}形式函数,则不添加"号。在JS代码中,如果不在标记里写事件代码,而右边的形式函数也不添加"号,例如:oP.onclick=function(){ //设置事件监听函数
alert('我被点击了'); }h267.html文件内容2388<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>IE的监听函数</title><scriptlanguage="javascript">functionfnClick(){ alert("我被点击了"); oP.detachEvent("onclick",fnClick); //点击了一次后删除监听函数,不能写成fnClick()2389}varoP;window.onload=function(){ oP=document.getElementById("myP"); //找到对象
oP.attachEvent("onclick",fnClick);//添加监听函数,注意fnClick函数不能写成fnClick()}</script></head>2390<body> <div> <pid="myP">ClickMe</p> </div></body></html>结果:IE9.0浏览器和其它主流浏览器都不能用attachEvent()监听函数和除去监听函数detachEvent()。在IE6.0上能够运行此网页代码!2391上例通过实验告诉我们,目前的上流浏览器都能使用onclick=的方法来监听事件,而IE6.0等低版本的浏览器要用attachEvent()函数来持续地监听事件,并用detachEvent()来删除持续地监听事件。2392当采用了两个监听函数时,响应会怎么样?结论:会响应后面那个监听函数。h268.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>多个监听函数</title><scriptlanguage="javascript">2393/*functionfnClick1(){ alert("我被fnClick1点击了");}functionfnClick2(){ alert("我被fnClick2点击了");}*/2394varoP;window.onload=function(){ oP=document.getElementById("myP"); //找到对象
//添加监听函数1 oP.onclick=function(){ alert("我被fnClick1点击了");}//添加监听函数2 oP.onclick=function(){ alert("我被fnClick2点击了");}}2395</script></head><body><div><pid="myP">ClickMe</p></div></body></html>2396在上例中,值得注意是,在监听函数右边,即在oP.onclick=右边放置了一个形式函数,如果在此处用实际函数调用,情况会怎样?把上例中以下代码的注释符去掉,再更改代码如下,成为h269.html文件的内容,那么结果会怎么样?结果:仍然是最后那个监听有响应。h269.html文件内容2397<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>多个监听函数</title><scriptlanguage="javascript">functionfnClick1(){ alert("我被fnClick1点击了");}2398functionfnClick2(){ alert("我被fnClick2点击了");}</script></head><body><div><pid="myP">ClickMe</p></div><scriptlanguage="javascript">2399var oP=document.getElementById("myP"); //找到对象
//添加监听函数1 oP.onclick=fnClick1;//添加监听函数2 oP.onclick=fnClick2; </script></body></html>var oP=document.getElementById("myP");//找到对象2400//添加监听函数1,fnClick1不能写成fnClick1() oP.onclick=fnClick1;//添加监听函数2,fnClick2不能写成fnClick2() oP.onclick=fnClick2; </script></body></html>注:如果函数fnClick1()有形式参数,则在引用时要使用实参,那么在调用时要有fnClick1(实参)。2401从上例的结果可以看出,当有两个监听函数时,后面那个监听函数有响应,前面那个没有响应。ie6.0低版本的浏览器使用attachEvent()监听函数,在主流浏览器里已经不适用了。还好,dom有标准的监听方法。标准的DOM定义了两个方法分别来添加和删除监听函数:2402[object].addEventListener("event_name",fnHandler,bCapture);[object].removeEventListener("event_name",fnHandler,bCapture);一看这两个函数,与AS3.0的监听函数和除去监听函数在形式上和函数名上完全一样,太棒了!event_name是事件名,事件名与以前不一样了,例如click,mousemove等,不再使用onclick,onmousemove等了。fnHandler是响应函数,与AS3.0相同。bCapture是逻辑值,当为true时事件流为捕获型,而为false时事件流为冒泡型。h270.html文件内容2403<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"""><html><head><title>标准DOM的事件监听</title><scriptlanguage="javascript">functionfnClick1(){ alert("我被fnClick1点击了");//oP.removeEventListener("click",fnClick2,false); //删除监听函数22404}functionfnClick2(){ alert("我被fnClick2点击了");}varoP;window.onload=function(){ oP=document.getElementById("myP"); //找到对象
oP.addEventListener("click",fnClick1,false); //添加监听函数1 oP.addEventListener("click",fnClick2,false); //添加监听函数22405}</script></head><body> <div> <pid="myP">ClickMe</p> </div></body></html>24062407上例实验结果说明,addEventListener监听器函数在主流浏览器里和IE浏览器里都使用正常,并且监听响应的顺序也正常了。在上例中,如果把下句代码的注释符除去,结果只有fnClick1有响应,而fnClick2没有响应。//oP.removeEventListener("click",fnClick2,false);取元素以后,然后使用addEventListener函数和removeEventListener函数,对所有浏览器都有效,以后要多使用这两个函数,太棒了。2408三、事件对象浏览器中的事件都是以对象形式存在的。IE浏览器与标准的DOM浏览器之间在获取事件对象时存在差别。IE浏览器中的事件对象是window对象的一个属性event,访问时通常采用如下方法:oP.onclick=function(){varoEvent=window.event;}尽管event是window对象的属性,但event对象还是只能在事件发生时被访问,所有的事件处理函数执行完之后,该对象就消失了。2409而标准的DOM中规定event对象必须作为惟一的参数传给事件处理函数,因此类似Firefox浏览器中访问事件对象时通常将其作为参数,代码如下:oP.onclick=function(oEvent){}因此,为了兼容IE和类似于Firefox的浏览器,通常采用以下方法获取事件对象,其实就是把两类浏览器获取事件对象的代码合二为一:oP.onclick=function(oEvent){if(window.event)oEvent=window.event;}2410浏览器取得了事件对象以后就可以通过一系列的事件对象的属性和方法函数来处理具体的事件了。例如鼠标事件、键盘事件和浏览器事件等。在下表中罗列了事件常用的属性和方法。在下表中可以看出,标准DOM浏览器与IE浏览器在常用事件属性和方法上多数相同。在下表中,type属性对所有浏览器兼容,它获取事件类型,返回类似于click、mousemove等事件类型的值。varsType=oEvent.type这对于同一函数处理多种事件十分有用。24112412h271.html文件内容<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 某高中副校长在11月升旗活动上的讲话
- 2023年中考地理模拟卷(四)
- 湛江-PEP-2024年10版小学三年级下册英语第5单元寒假试卷
- 《管理学原理》期末考试复习题库(含答案)
- 骨盆骨折护理常规
- 云南省大理市2024-2025学年高三年级上册规模化统一检测地理试题(含答案)
- 2023年群路密码机系列投资申请报告
- 2024年密封垫及类似接合衬垫项目资金筹措计划书代可行性研究报告
- 强化财政投融资体制促进积极财政政策的实施
- 耐高温自润滑聚酰亚胺复合材料
- Unit4-Hows-the-weather-today-说课(课件)人教精通版英语四年级上册
- 大学新生心理压力与情绪管理策略与心理调整与发展计划
- 空乘人员生涯发展展示
- 黄旭华(修订版)
- 子宫内膜异位症术后护理课件
- 医疗器材广告推广方案
- 保险基础知识课件
- 病毒学-流感病毒的变异与预防策略教学教案
- 干部履历表(中共中央组织部2015年制)
- “订餐协议书:团体订餐服务合作协议”
- 小学各年级小学一年级提高思维能力的方法主题班会
评论
0/150
提交评论