根据W3CDOM规范,DOM是html与XML的应用编程接口(API),DOM将整个页面映射为一个由层次节点组成的文件。有1级、2级、3级共3个级别。
DOM简介:
1、DOM:DocumentObjectModel(简称文档对象模型),是专门用于操作网页内容API一套标准!网页内容:字符、图片等各种资源
2、核心DOM:操作一切结构化文档的API标准!特点:强大,万能;缺点:操作繁琐。
3、HTMLDOM:专门操作HTML网页的API标准--针对核心DOM中部分API进行了简化!优点:操作相对简化;缺点:非万能。
4、对比:实际开发中HTMLDOM使用频率相对较高,只有当HTMLDOM无法实现某些功能时才会使用核心DOM。
5、DOM树:网页中一切内容都在内存中以树状结构存储,每项内容都在这个树上有一个节点。每个DOM树都有一个根节点:document节点。
6、节点对象:DOM上每一个节点,都是一个节点对象,提供了操作节点的API。
节点对象的属性:
1、nodeType:保存着节点的类型名!--不能明确获知节点名称
2、nodeName:保存节点的名称!--区分不同元素
3、nodeValue:保存元素的值!
正式操作DOM:增删改查!操作流程:获取能够操作的元素--目标元素--绑定事件--获取需要操作的元素--事件具体操作
查找/获取:
html中不需要获取直接使问的元素:
document.documentElement==>html
document.head==>head
document.body==>body
1、按照节点之间的层级关系:如果已经获取到一个元素,想找其周围元素
1>父子级:
child.parentNode:获取父节点--返回父节点
parent.childNodes:获取字节的--可以返回多个
parent.firstchild:获取父节点中第一个字节点
parent.lastchild:获取父节点中最后一个字节点
2>兄弟级:
elem.nextsibling:获取下一个兄弟节点
elem.previoussibling:获取上一个兄弟节点
问题:容易受到空字符影响!
2、解决方案:元素树:只包含元素的树状结构。元素树并非新的一个树,只是DOM树结构的一部分
1>父子级:
child.parentElement:获取父节元素--返回父级元素
parent.chidren:获取子元素--可以返回多个
parent.firstElementchild:获取父元素中第一个子元素
parent.lastElementchild:获取父元素中最后一个子元素
2>兄弟级:
elem.nextElementSibling:获取下一个兄弟元素
elem.previousElementSibling:获取上一个兄弟元素
遍历节点数/元素树
方式1:递归
步骤:定义一个方法,查找一个父节点下面所有的子节点--对遍历到的每个字节,再执行与父节点相同的方法。
步骤:定义一个方法,传入一个节点对象,获取并遍历每一个子节点
functioniterator(elem){
varchildren=elem.childNodes;
for(vari=0;i<children.length;i++co){
console.log("当前节点类型是:"+elem[i].nodeType);
console.log("当前节点名称是:"+elem[i].nodeName);
}
}
注意:递归的使用效率很低,不介意使用!
方式2:使用节点迭代对象
步骤1、创建一个节点迭代对象:variteartor=document.createNodeIterator(parent,NodeFilter.SHOW_ALL,null,false);
步骤2、反复调用iterator的nextNode()
作用:返回当前遍历到的节点;自动跑到下一个节点;自动返回null退出。
类数组对象:长得像数组,但不是数组
动态集合:不实际存储值,每次访问都会重新去查找DOM树!
问题:每次循环判断时都会去查找DOM树,浪费性能
处理:在判断之前,事先保存值。
操作DOM的步骤:
1、获取目标元素
2、绑定事件:再获取的元素对象上使用
elem.on事件名=function(){
3、获取需要操作的元素
4、操作元素
}
查找元素的内容
1、按照父子级和兄弟关系查找节点/元素
2、按照HTML特性查找
1>根据元素的IDS属性查找:varelem=document.getElementById("ID值");
注意:只能通过document调用;只能返回一个元素!
2>根据元素的标记名查找:varelems=parent.getElementByTagName("标记名");
注意:返回一个类数组的动态集合;可以通过任意父节元素调用;查找不限层级!
3>根据元素的name属性查找:varelems=document.getElementsByName("name属性值");
注意:返回一个类数组的动态集合;只能用document调用!
4>根据元素的class属性查找:varelems=parent.getElementsByClassName("class值");
注意:返回一个类数组的动态集合;可以通过任意父级元素调用;查找不限层级;只要元素包含指定的class取值即可!
3、根据css选择器查找元素--重要
1>查找一个元素:varelem=parent.querySelector("选择器");
2>查找多个元素:varelems=parent.querySelectorAll("选择器");
注意:
1、以上两个API返回的不是动态集合,即使反复访问也不会反复查找DOM。
2、在低版本的浏览器中,不支持此类API。
总结:
1、已经获取了一个元素,想查找附近的元素--通过元素之间的关系查找
2、如果只知道一个条件,想获取元素--通过html特性查找
3、如果条件比较复杂--通过选择器查找
修改元素的内容
1、.innerHTML:获取/修改元素中内容区域的内容
内容区域:从起始标记到结束标记之间的区域
取值:elem.innerHTML//获取元素elem的内容区域的内容
赋值:elem.innerHTML="新值";
注意:此API赋值的内容,浏览器会当作html代码解析!
2、.textContent:获取/修改元素elem的内容标记内的文本
取值:elem.textContent
赋值:elem.textContent="新值";
注意:此API赋值的内容,浏览器不会解析特殊字符,就是普通文本
3、.value:获取表单元素的value属性值
获取:varstyle1=elem.style.属性名;
修改:elem.style.属性名=值;
套路:可以将需要的样式设置在一个类中,通过修改class属性引入这个类。
elem.className="类名";
DOM操作属性
1、标准属性:所有元素都支持的属性(id,name,class,title,style......),HTML标准中指定的属性----w3c
2、核心DOM中的API:
1>获取一个元素指定的属性:elem.getAttribute("属性名");
2>修改一个元素指定属性的值:elem.setAttribute("属性名","新值");
3>判断一个元素是否具有指定属性:elem.hasAttribute("属性名");
4>移除一个元素指定的属性:elem.removeAttribute("属性名");
注意:不仅将属性值删除,属性名也会删除。
HTMLDOM操作属性
在HTMLDOM中,已经将元素支持的标准属性封装在家元素对象中,可以通过.之间访问!
1、获取属性:elem.属性名;
2、修改/添加:elem.属性名="值";
3、判断:elem.属性名!=="";
4、删除:elem.属性名="";
操作页面的元素
添加一个元素:
1>创建一个元素:varelem=document.createElement("新元素");
2>添加必要的属性和内容:elem.属性名1=值;elem.属性名2=值;elem.innerHTML="百度一下";
3>将创建的新元素追加到DOM树中指定的父节点下!
1、在父元素的末尾追加新元素:parent.appendChild(elem);
2、中间插入:将新元素插入到兄弟元素之间:parent.insertBefore(elem,兄弟元素);
3、替换:parent.replace(elem,被替换的元素);
DOM操作元素
如果进行了DOM操作元素,网页将重新layout。如果频繁的操作DOM,会造成性能浪费。
解决方法:如果需要向父节点中追加多个字节点,可以先将需要添加的子元素先保存在一个虚拟的临时父节点下。最后一次性将所有字节点追加到DOM中真实父节点下!
步骤1:创建多个子节点:varzhy1=document.createElement("a");varzhy2=document.createElement("b");
步骤2:创建虚拟父节点:varfrag=document.createElementFragment();
步骤3:将子节点追加到虚拟父节点:frag.appendChild(zhy1);frag.appendChild(zhy2);
步骤4:最后将虚拟父节点追加到真正的父节点中:parent.appendChild(frag);
注意:将临时节点追加到DOM中,临时的片段frag会被释放,真正追加到DOM的只有那些子元素!
HTMLDOM简化操作
在操作常见的HTML元素时,HTMLDOM提供了一些简化操作。包括了img,select,option,table/行分组/tr/td,from
1、img:varimg=newImage();
2、select:value;selectdIndex;option;length
解析:value:获取被选中的选项的value值;selectedIndex:获取当前被选中的选择的下标;option:获取内部所有的option元素集合;length:获取option所得集合的长度。
3、option:varopt=newOption();
4、table:外层的table管着行分组(thead,tbody,tfoot);
5、创建行分组:已经获取到table元素,可以直接调用table创建行分组元素
varthead=table.createTHead();
vartbody=table.createTBody();
vartfoot=table.createTFoot();
6、删除行分组:调用table删除内部的行分组,注意只能删表头和表尾。
table.deleteTHead();
table.deleteTFoot();
7、获取表格中的行分组:可以有多个表主体。
table.tHead;
table.tBodies;
table.tFoot;
8、行分组控制行
创建行:行分组insertRow(i);
删除行:行分组.deleteRow(i);
获取行:行分组.Rows;
9、行分组控制列
创建列:tr.insertCell(i);
删除列:tr.deleteCell(i);
获取列们:tr.Cells;
10、from:获取页面上的from元素:
document.from;获取页面元素中的表单元素
document.forms[i/id];根据表单的序号,或者id值获取对应表单!
from.elements;获取表单中所有的表单元素!
返回一个类数组对象,具有length和下标!
DOM实际上是以面向对象方式描述的文档模型。DOM定义了表示和修改文档所需的对象、这些对象的行为和属性以及这些对象之间的关系。可以把DOM认为是页面上数据和结构的一个树形表示,不过页面当然可能并不是以这种树的方式具体实现。