【DOM】
DOM是Document Object Model(文档模型)的简写,它表示访问和操作文档的API。当网页被加载到客户端后,浏览器会调用DOM API组件,根据一定规范解析文档,创建文档对象索引模型。
【DOM树节点】
<html> <head> <meta charset="UTF-8"> <title>DOM对象节点</title> </head> <body> <h1>标准DOM</h1> <p>这是一份简单的<strong>文档对象模型</strong></p> <ul> <li>D表示文档,DOM的物质基础</li> <li>O表示对象,DOM的思想基础</li> <li>M表示模型,DOM的方法基础</li> </ul> </body> </html>
【节点】
节点(node)在网络理论中,代表是网络中的一个连接点,网络是由节点构成的集合。只有节点之间的连接正常,人们才能在互联网中正常的访问。
在HTML中,主要分为节点:元素节点、属性节点、文本节点。元素节点就是HTML的标签元素,属性节点就是HTML元素的属性、文本节点就是HTML元素的文本内容。在这里我们需要注意的是空格和回车键也是一个文本节点,后面我们会涉及到。
因为属性总是出现在标签元素里面,所以属性节点总是被包含在元素节点当中。而文本节点无子父继承关系,所以在文本节点之中也无其他节点元素。
【节点的获取】
JavaScript为我们提供了三大节点的获取方法,分别是getElementById()、getElementsByClassName()、getElementsByTagName()分别获取指定的元素节点或集合。
JavaScript为DOM提供了一个通过标签元素的id名获取精确节点的方法getElementById(),该方法返回的一个指定id名的元素节点。例如,从文档中获取id名为Test的元素节点
document.getElementById("Test");
既然可以通过元素的id名获取元素节点,那么自然可以通过类名class获取元素节点,只是不同的是,前者返回的是指定的元素节点,而后者返回的是指定类名的节点数组,通过指定下标去访问元素节点。例如,从文档中获取class名为Group的元素节点
document.getElementsByClassName("Group");
HTML是有元素标签组成的文档,所以我们自然可以通过元素标签去获取元素节点。由于一个HTML中可以存在多个相同标签,所以与类名节点一样,通过元素标签返回的也是一个节点数组。例如,从文档中获取标签名为li的元素节点
document.getElementsByTagName("li");
JavaScript和Java都严格区分大小写,所以请按照上面的格式来写,由于DOM的获取方法已经标明获取元素的类型,所以我们并不需要在括号里面加入#或.来表名获取的类型。并且元素名是被包含在双引号或单引号里面,虽然你不加也没关系,但是请遵循语法规范,因为一个名称一定是字符串,如果不加双引号的话,谁知道这个变量是什么数据类型?只是在JavaScript脚本域中,如果匹配不到该变量,JS默认将其视为一个字符串而已,如果你定义了该变量为字符串,那么你可以不加,因为JavaScript可以获取到该变量的字符串值。
JS代码 function accu(txts){ Cons = document.getElementById("contents"); if(txts == "getElementById"){ Cons.innerHTML = "通过getElementById获取精确的节点对象,然后再访问其节点对象,例如:document.getElementById('DivC1').innerHTML</br>获取id为DivC1的节点HTML内容:"+document.getElementById("DivC1").innerHTML }else if(txts == "getElementsByClass"){ var sum = document.getElementsByClassName("DivC"); Cons.innerHTML ="通过getElementsByClass获取相同类名的节点集合,通过下标去访问指定节点,例如:DivC = getElementsByClass('DivC')</br>访问DIvC节点集的第一个对象DivC[0]:"+sum[0].innerHTML+"</br>访问DIvC节点集的第二个对象DivC[1]:"+sum[1].innerHTML+"</br>访问DIvC节点集的第三个对象DivC[2]:"+sum[2].innerHTML }else if(txts == "getElementByTagName"){ var sum = document.getElementsByTagName("li"); Cons.innerHTML = "通过getElementByTagName获取指点标签节点集合,例如:li = document.getElementByTagName(li)</br>访问li元素节点集的第一个对象li[0]:"+sum[0].innerHTML+"</br>访问li元素节点集的第二个对象li[1]:"+sum[1].innerHTML+"</br>访问li元素节点集的第三个对象li[2]:"+sum[2].innerHTML } }
HTML代码 <h1>标准DOM</h1> <p>这是一份简单的<strong>文档对象模型</strong></p> <div id="ContDiv"> <div id="DivSelf"> <ul> <li class="DivC" id="DivC1">Div内容1</li> <li class="DivC" id="DivC2">Div内容2</li> <li class="DivC" id="DivC3">Div内容3</li> </ul> </div> </div> <input type="button" value="精确获取指点节点" onclick="accu('getElementById')"/> <input type="button" value="获取指点节点集合" onclick="accu('getElementsByClass')"/> <input type="button" value="获取指点标签节点" onclick="accu('getElementByTagName')"/> <div id="contents"></div>
【节点的自身属性】
从上面的介绍中,我们知道如何去获取一个节点对象或节点数组。我们知道对象含有属性和方法,这里自身属性指的就是节点本身的属性,JavaScript主要为我们提供了nodeName、nodeType、nodeValue属性返回节点名、节点属性和节点值。如果该节点是个元素节点,nodeName返回的是大写标签名、nodeValue为空;如果该节点是属性节点,则nodeName返回的是大写的属性名,若该节点是文本节点,则nodeName返回的是文本
节点可以拥有不同的特性,因此可以把节点的属性分为多种类型,常见的如下所示
节点类型 |
nodeType 返回值 |
nodeName 返回值 |
nodeValue 返回值 |
说明 |
Document |
9 |
#document |
Null |
表示整个文档(DOM树的根节点) |
Element |
1 |
元素名称 |
Null |
表示元素 |
Atrr |
2 |
属性名称 |
属性值 |
表示属性 |
Text |
3 |
#text |
节点内容 |
表示元素或属性中的文本内容 |
window.onload = function(){ //getElementsByTagName返回的是指定标签的数组 var tag = document.getElementsByTagName("ul")[0]; //获取该列表的所有子节点 var a = tag.childNodes; var Cont = document.getElementById("content"); var sum; for(var i=0;i<a.length;i++){ sum += "<div class='conLis'>节点返回值:"+ a[i].nodeName + "</br>节点类型:" + a[i].nodeType + "</br>节点值:" + a[i].nodeValue + "</br>当前节点的父节点:" + a[i].parentNode + "</br>当前节点的第一个子节点:" + a[i].firstChild + "</br>当前节点的最后一个子节点:" + a[i].lastChild + "</br>获取上一个同级节点(兄弟节点):" + a[i].previousSibling + "</br>获取下一个同级节点(兄弟节点)" + a[i].nextSibling + "</div>"; } sum += "<div class='conLis'>数组长度为:" + a.length + "</div>"; Cont.innerHTML = sum; }
【节点的访问操作】
<!--HTML代码--> <h1>标准DOM</h1> <p>这是一份简单的<strong>文档对象模型</strong></p> <ul> <li>D表示文档,DOM的物质基础</li> <li>O表示对象,DOM的思想基础</li> <li>M表示模型,DOM的方法基础</li> </ul> <div id="content"></div>
//JavaScript代码 //getElementsByTagName返回的是指定标签的数组 var tag = document.getElementsByTagName("ul")[0]; //获取该列表的所有子节点 var a = tag.childNodes; var Cont = document.getElementById("content"); var sum; for(var i=0;i<a.length;i++){ sum += "<div class='conLis'>节点返回值:"+ a[i].nodeName + "</br>节点类型:" + a[i].nodeType + "</br>节点值:" + a[i].nodeValue + "</br>当前节点的父节点:" + a[i].parentNode + "</br>当前节点的第一个子节点:" + a[i].firstChild + "</br>当前节点的最后一个子节点:" + a[i].lastChild + "</br>获取上一个同级节点(兄弟节点):" + a[i].previousSibling + "</br>获取下一个同级节点(兄弟节点)" + a[i].nextSibling + "</div>"; } sum += "<div class='conLis'>数组长度为:" + a.length + "</div>"; Cont.innerHTML = sum;
上述代码中,我们获取文档中所有的ul标签,从HTML代码可以看到只存在一个ul标签,所以通过0下标可以访问该元素节点,通过该节点的childNodes可以获取返回该节点的所有子节点数组。
从HTML代码结构我们可以看出ul的内部结构如下图所示
但其实这样想是错的,因为前面说过,一个空格字符和一个回车字符,浏览器都会默认为一个文本节点,所以真正的ul内部结构图如下图所示
接下来我们运行代码,来猜测我们的想法,并看看浏览器是如何解析并得出结果的
从结果可以看出,ul的子节点数正好是7,最特殊的莫过于顶部节点和尾部节点,前者已无前兄弟节点、后者已无后兄弟节点,所以值均为空。文本节点是不存在子节点的,所以凡是文本节点,它的子节点均为null。
【节点内容的操作】
<!-- HTML代码 --> <h1>标准DOM</h1> <p>这是一份简单的<strong>文档对象模型</strong></p> <p>动态增加文档内容有4个基本属性:innerHTML、innerText、outerHTML、outerText。只有innerHTML支持绝大部分的浏览器,其他属性只有IE支持</p> <ul id="self"> <li id="li1">D表示文档,DOM的物质基础</li> <li id="li2">O表示对象,DOM的思想基础</li> <li id="li3">M表示模型,DOM的方法基础</li> <li id="li4"><b>最后一个测试文本</b></li> </ul> <input type="button" id="Bth" value="innerHTML" onclick="inner('innerHTML')"/> <input type="button" id="Bth" value="innerText" onclick="inner('innerText')"/> <input type="button" id="Bth" value="outerHTML" onclick="inner('outerHTML')"/> <input type="button" id="Bth" value="outerText" onclick="inner('outerText')"/>
//JavaScript代码 function inner(txts){ if(txts == "innerHTML"){ document.getElementById("li1").innerHTML = "<b>innerHTML测试文本</b>"; }else if(txts == "innerText"){ document.getElementById("li2").innerText = "<b>innerText测试文本</b>" }else if(txts == "outerHTML"){ document.getElementById("li3").outerHTML = "<b>outerText测试文本,将本身的HTML元素也给覆盖了</b>" }else if(txts == "outerText"){ document.getElementById("li4").innerText = "outerText测试文本" } }
从上图可以看出,innerHTML表示的是将内部结构改为HTML元素结构,浏览器会识别你插入的字符串是否包含HTML标签,若有则创建该元素节点。innerText表示的是将内部结构改为文本结构,所以即使插入的字符串包含HTML标签,浏览器也会认定他就是一个字符串,而不创建该节点。这两种属性修改的是指定对象的内部结构,而outerHTML、outerText功能和inner属性同理,但最主要的一点是,它会将自身的结构改变。
【节点的增、删、改、插操作】
<!-- HTML代码 --> <div id="Container"> <div id="buttonContainer"> <div id="inputContainer"> <input type="button" name="Bth" id="Bth3" value="插入节点appendChild" /> <input type="button" name="Bth" id="Bth3other" value="插入节点insertBefore" /> </div> <input type="button" name="Bth" id="Bth1" value="创建节点createElement" /> <input type="button" name="Bth" id="Bth2" value="复制节点cloneNode" /> <input type="button" name="Bth" id="Bth4" value="删除节点removeChild" /> <input type="button" name="Bth" id="Bth5" value="替换节点replaceChild" /> </div> <div id="addHtmlContainer"> <div> <p>插入节点文本区</p> <div id="three"><div id="threeElement">插入区的一个元素节点</div></div> </div> <div> <p>添加节点文本区</p> <div id="one"></div> </div> <div> <p>复制节点文本区</p> <div id="two"></div> </div> <div> <p>删除节点文本区</p> <div id="four"><div id="fourElement">删除区的一个元素节点</div></div> </div> <div> <p>替换节点文本区</p> <div id="five"><div id="fiveElement">替换区的一个元素节点</div></div> </div> <div id="txtContainer" style="padding-bottom: 0px;"> <h4>来自txtContainer元素节点的标题</h4> </div> </div> </div>
//JavaScript代码 window.onload = function(){ var Bth1 = document.getElementById("Bth1"); //按钮对象 var Bth2 = document.getElementById("Bth2"); //按钮对象 var Bth3 = document.getElementById("Bth3"); //按钮对象 var Bth3other = document.getElementById("Bth3other"); //按钮对象 var Bth4 = document.getElementById("Bth4"); //按钮对象 var Bth5 = document.getElementById("Bth5"); //按钮对象 var txtCont = document.getElementById("txtContainer"); //操作的文本对象 var num = 0; //创建标签的累计个数 //Bth1 --- 创建节点createElement Bth1.addEventListener("click",function(){ //添加一个标准DOM监听事件 var Element = document.createElement("div"); //创建一个HTML标签 document.getElementById("one").appendChild(Element); //指定该标签的父元素 //添加新标签的属性 Element.className = "childs child"+(++num); //指定新标签的id Element.id = "newID"+num; //指定新标签的类名 Element.innerText = "这是新建的第"+num+"个div标签"; //创建标签内容 },false); //Bth2 --- 复制节点cloneNode Bth2.addEventListener("click",function(){ //克隆元素节点txtContainer的所有字节点内容true var Element = txtCont.cloneNode(true); var twoElement = document.getElementById("two"); //将克隆节点定位two节点的子节点 twoElement.appendChild(Element); },false); //Bth3 --- 插入节点appendChild Bth3.addEventListener("click",function(){ //使用appendChild插入节点是从指点节点的底部开始插入 document.getElementById("threeElement").appendChild(txtCont); },false); //Bth3other --- 插入节点insertBefore Bth3other.addEventListener("click",function(){ document.getElementById("three").insertBefore(txtCont,document.getElementById("threeElement")); },false); //Bth4 --- 删除节点removeChild Bth4.addEventListener("click",function(){ if(document.getElementById("fourElement")){ document.getElementById("four").removeChild(document.getElementById("fourElement")); } },false); //Bth5 --- 替换节点replaceChild(将父节点的某个子节点替换成指点节点) Bth5.addEventListener("click",function(){ if(document.getElementById("fiveElement")){ document.getElementById("five").replaceChild(txtCont,document.getElementById("fiveElement")); } },false); }
appendChild
insertBefor
createElement
cloneNode
removeChild
replaceChild
内容未完全