DOM(一)
- DOM可以将任何HMLT或XML文档描绘成一个由多层节点构成的结构,节点氛围几种不同的类型,每种类型分别表示文档中不同的信息及标记,每个节点都拥有各自的特点、数据和方法。
- Node类型
DOM1级定义了一个Node接口,该接口将由DOM中的所以节点类型实现,除了IE之外,其他浏览器都可以访问到这个类型,js中的所有节点类型都继承自Node类型。
每个节点都有一个nodeType属性,用于表明节点的类型,下面12个数值常来表示类型:
- Node.ELEMENT_NODE(1);
- Node.ATTRIBUTE_NODE(2);
- Node.TEXT_NODE(2);
- Node.CDATA_SECTION_NODE(4);
- Node.ENTITY_REFERENCE_NODE(5);
- Node.ENTITY_NODE(6);
- Node.PROCESSING_INSTRUCTION_NODE(7)
- Node.COMMENT_NODE(8)
- Node.DOCUMENT_NODE(9)
- Node.DOCUMENT_TYPE_NODE(10)
- Node.DOCUMENTY_FRAGMENT_NODE(11)
- Node.NOTATION_NODE(12)
通过比较上面这些常量,可以很容易地确定节点的类型,例如:
If(someNode.nodeType==Node.ELEMENT_NODE){//在ie中无效 alert(“Node is an element”); }
由于ie没有公开Node类型的构造函数,因此上面的代码在ie中会导致错误,为了确保跨浏览器兼容,最好还是将nodeType属性和数字进行比较,如下:
if(someNode.nodeType==1){ alert(“Node is an element.”); }
要了解节点的具体信息,可以使用nodeName和nodeValue这两个属性,这两个属性的值完全取决于节点的类型,在使用这两个值以前,最后是像下面这样先检测一下节点的类型。
if(someNode.nodeType==1){ value=someNode.nodeName; }
- 节点关系
每个节点都有一个childNodes属性,其中保存着一个NodeList对象,NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。虽然可以通过方括号语法来方位NodeList的值,而且这个对象也有length属性,但它并不是Array的实例。NodeList对象的独特之处在于,它实际上是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反应在NodeList对象中。
下面例子展示了如何访问保存在NodeList中的节点,可以通过方括号,也可以使用item方法。
var firstChild=someNode.childNodes[0]; var secondChild=someNode.childNodes.item(1); var count=someNode.chilNodes.length;
对arguments对象使用Array.prototype.slice()方法可以将其转换为数组,而采用同样方法,也可以将NodeList对象转换为数组,如下:
var arrayOfNodes=Array.prororype.slice.call(someNode.childNodes,0)’
除IE8及更早版本之外,这行代码能在任何浏览器中运行,由于IE8及更早版本将NodeList实现为一个COM对象,而我们不能像使用Jscript对象那样使用这种对象,因此上面的代码会导致错误,要想在ie中将NodeList转换为数组,必须手动枚举所有成员。如下:
function convertToArray(nodes){ var array=null; try{ array=Array.prororype.slice.call(nodes,0); }catch(ex){ Array=new Array(); for(var i=0,len=nodes.length;i<len;i++){ array.push(nodes[i]); } } return array; }
每个节点都有一个parentNode属性,该属性指向文档树中的父节点,包含在childNodes列表中的所有节点都具有相同的父节点,因此它们的parentNode属性都指向同一个节点。此外,包含在childNodes列表中的每个节点相互之间都是同胞节点,通过使用列表中每个节点的previousSibling和nextSibling属性,可以访问同一列表中的其他节点,列表中的第一个节点的previousSibling属性为null,而列表中最后一个节点的nextSibling属性的值同样为null,如下:
if(someNode.nextSibling===null){ alert(“Last node in the parent’s childNodes list.”); }else if(someNode.previousSibling===null){ alert(“First node in the parent’s childNodes list.”); }
父节点的firstChild和lastChild属性分别指向其childNodes列表中的第一个和最后一个节点,其中,someNode.firstChild的值始终等于someNode.childNodes[0],而someNode.lastChild的值始终等于someNode.childNodes[someNode.childNodes.length-1]。在只有一个节点的情况下,firstChild和lastChild指向同一个节点,如果没有子节点,那么firstChild和lastChild的值均为null。
所有节点都有的最后一个属性是ownerDocument,该属性指向表示整个文档的文档节点,这种关系表示的是任何节点都属于它所在的文档,任何节点都不能同时存在于亮哥或更多个文档中,通过这个属性,我肯可以不必再节点层次中通过层层回溯到达顶端,而是可以直接访问文档节点。
DOM提供了一些操作节点的方法,其中,最常用的方法是appendChild,用于向childNodes列表的末尾添加一个节点,添加节点后,childNodes的新增节点、父节点及以前的最后一个子节点的关系指针都会相应得到更新,更新完成后,appendChild返回新增的节点,如下:
var returnedNode=someNode.appendChild(newNode); alert(returnedNode==newNode); //true alert(someNode.lastChild==newNode); //true
如果传入到appendChild中的节点已经是文档的一部分,那结果就是将该节点从原来的位置转移到新位置,如下:
var returnedNode=someNode.appendChild(someNode.firstChild); alert(returnedNode==someNode.firstChild); //false alert(returnedNode==someNode.lastChild); //true
如果需要把节点放在childNodes列表中某个特定的位置上,而不是放在末尾,那么可以使用insertBefore方法,这个方法接受两个参数:要插入的节点和作为参照的节点,插入节点后,被插入的节点会变成参照节点的前一个同胞节点,同时被方法返回。如下例子:
returnedNode=someNode.insertBefore(newNode,null); alert(newNode==someNode.lastChild); //true var returnedNode=someNode.inserBefore(newNode,someNode.firstChild); alert(retrunedNode==newNode); //true alert(newNode==someNode.firstChild); //true returnedNode=someNode.insertBefore(newNode,someNode.lastChild); alert(newNode==someNode.chlidNodes[someNode.childNodes.length-2]); //true
replaceChild方法接受的两个参数是:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置,如下:
var returnedNode=someNode.replaceChild(newNode,someNode.firstChild); returnedNode=someNode.replaceChild(newNode,someNode.lastChild);
使用replaceChild插入一个节点时,该节点的所有关系指针都会从被它替换的节点复制过来。
removeChild方法移除节点。这个方法移除的节点仍然为文档所有,只不过在文档中已经没有了自己的位置。
cloneNode方法用于创建调用这个方法的节点的一个完全相同的副本,cloneNode方法接受一个布尔值参数,表示是否执行深复制,在参数为true的情况下,执行深复制,也就是在复制节点及其整个子节点树,在参数为false的情况下,执行浅复制,即只复制节点本身,复制后返回的节点副本属于文档所有。
- Document类型
Js通过Document类型表示文档,在浏览器中,document对象是HTMLDocument的一个实例,表示整个html页面。而且,document对象是window对象的一个属性,Document节点具有下列特性:
- nodeTye的值为9;
- nodeName的值为“#document”;
- nodeValue的值为null;
- parentNode的值为null;
- ownerDocument的值为null;
- 其子节点可能是一个DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction或Coment。
Document类型可以表示HTML页面或者其他基于XML的文档,不过,最常见的应用还是作为HTMLDocument实例的document对象,通过整个文档对象,不仅可以取得与页面的有关信息,而且还能操作页面的外观及其底层结构。
- 文档的子节点
虽然DOM标准规定Document节点子节点可以是DocumentType、Element、ProcessingInstructior或Comment,但还有两个内置的访问其子节点的快捷键,第一个就是documentElement属性,该属性始终指向HTML页面中的<html>元素。另一个就是通过childNodes列表返回文档元素,但通过documentElement属性则更快捷,更直接的访问该元素。
作为HTMLDocument的实例,document对象还有一个body属性,直接指向body元素,因为开发人员经常要使用这个元素,所以document.body在js代码中出现的频率非常高,如下:
var body=document.body;
所有浏览器都支持document.documentElement和document.body属性。
Document另一个可能的子节点时DocumentType,通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体,可以通过doctype属性来访问它的信息。
var doctype=document.doctype;
浏览器对document.doctype的支持差别很大,总结如下:
- IE8之前版本:如果存在文档类型声明,会将其错误地理解为一个注释并把它当作Comment节点;而document.doctype的值始终未null。
- IE9+及Firefox:如果存在文档类型声明,则将其作为文档的第一个子节点;document.doctype是一个DocumentType节点,也可以通过document.firstChild或document.childNodes[0]访问同一个节点。
- Safari、Chrome和Opera:如果存在文档类型声明,则将其解析,但不作为文档子节点,document.doctype是一个DocumentType节点,但该节点不会出现在document.childNodes中。
如下:
<!--第一条注释 --> <html> <body> </body> </html> <!—-第二条注释-->
看起来这个页面应该有3个节点:注释、html元素、注释。现实中浏览器在处理位于html外部的注释方面存在如下差异:
- IE8之前版本、Safari 3.1及更高版本、Opera和Chrome职位第一条注释创建节点,不为第二天注释创建节点,结果,第一条注释就会成为document.childNodes中的第一个子节点
- IE9及更高版本会将第一条注释创建为document.childNodes中的一个注释节点,也会将第二条注释创建为document.childNodes中的注释子节点。
- Firefox以及Safari 3.1之前的版本会完全忽略这个两条注释。
DOM(一)的更多相关文章
- 关于DOM的操作以及性能优化问题-重绘重排
写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...
- 读书笔记:JavaScript DOM 编程艺术(第二版)
读完还是能学到很多的基础知识,这里记录下,方便回顾与及时查阅. 内容也有自己的一些补充. JavaScript DOM 编程艺术(第二版) 1.JavaScript简史 JavaScript由Nets ...
- 页面嵌入dom与被嵌入iframe的攻防
1.情景一:自己的页面被引入(嵌入)至别人的页面iframe中 if(window.self != window.top){ //url是自己页面的url window.top.location.hr ...
- 通俗易懂的来讲讲DOM
DOM是所有前端开发每天打交道的东西,但是随着jQuery等库的出现,大大简化了DOM操作,导致大家慢慢的“遗忘”了它的本来面貌.不过,要想深入学习前端知识,对DOM的了解是不可或缺的,所以本文力图系 ...
- HTML DOM 介绍
本篇主要介绍DOM内容.DOM 节点.节点属性以及获取HTML元素的方法. 目录 1. 介绍 DOM:介绍DOM,以及对DOM分类和功能的说明. 2. DOM 节点:介绍DOM节点分类和节点层次. 3 ...
- HTML DOM 对象
本篇主要介绍HTML DOM 对象:Document.Element.Attr.Event等4个对象. 目录 1. Document 对象:表示文档树的根节点,大部分属性和方法都是对元素进行操作. 2 ...
- 重撸js_2_基础dom操作
1.node 方法 返回 含义 nodeName String 获取节点名称 nodeType Number 获取节点类型 nodeValue String 节点的值(注意:文本也是节点) 2.inn ...
- 虚拟dom与diff算法 分析
好文集合: 深入浅出React(四):虚拟DOM Diff算法解析 全面理解虚拟DOM,实现虚拟DOM
- 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?
引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...
- jQuery学习之路(2)-DOM操作
▓▓▓▓▓▓ 大致介绍 jQuery作为JavaScript库,继承并发扬了JavaScript对DOM对象操作的特性,使开发人员能方便的操作DOM对象. ▓▓▓▓▓▓ jQuery中的DOM操作 看 ...
随机推荐
- Flask路由与蓝图Blueprint
需求分析: 当一个庞大的系统中有很多小模块,在分配路由的时候怎么处理呢?全部都堆到一个py程序中,调用@app.route? 显然这是很不明智的,因为当有几十个模块需要写路由的时候,这样程序员写着写着 ...
- 上了IPD和CMMI,为什么还要搞敏捷?
文/资深顾问 杨学明 现在国内许多产品创新型企业一旦研发团队上了规模,就会进行IPD体系的变革或CMMI的认证,但现在还有一种更加流程的开发模式,就是敏捷,华为公司早在2009年正式发文在全公司现在流 ...
- MongoDB 安装与配置
MongoDB下载 官方下载链接:https://www.mongodb.com/download-center/community MongoDB安装 简单,按提示安装即可.安装方式: 1. Com ...
- HBase架构设计
一.Client 包含访问HBase的接口并维护cache来加快对HBase的访问. 二.Zookeeper 1.保证任何时候,集群中只有一个master. 2.存储所有Region的寻址入口. 3. ...
- c/c++ 通用的(泛型)算法 之 只读算法,写算法,排序算法
通用的(泛型)算法 之 只读算法,写算法,排序算法 只读算法: 函数名 功能描述 accumulate 求容器里元素的和 equal 比较2个容器里的元素 写算法 函数名 功能描述 fill 用给定值 ...
- CentOS 7.0下解决ifconfig: command not found的方法
在CentOS7.0中输入ifconfig命令会遇到-bash: ifconfig: command not found. 在CentOS最小安装时是没有附带ifconfig,我们进入sbin目录下可 ...
- [Hive_add_8] Hive 常用参数配置
0. 说明 记录 Hive 常用参数的配置 1. 设置本地模式 让 Hive 自动使用 Hadoop 的本地模式运行作业,提升处理性能 适合小文件,一般用于测试 set hive.exec.mode. ...
- VueJs入门(一)
VueJs学习笔记:基本概念及简单demo Vue官方介绍:简单小巧的核心,渐进式技术栈,足以应付任何规模的应用. 简单小巧指的是vue.js压缩后仅有17KB,量轻.渐进式指的是我们学习和使用vue ...
- 排序算法之直接插入排序的思想以及Java实现
1,基本思想 假设待排序的数据是数组A[1-.n].初始时,A[1]自成1个有序区,无序区为A[2-.n].在排序的过程中,依次将A[i] (i=2,3,-.,n)从后往前插入到前面已排好序的子数组A ...
- FastCGI Error Number: 5 (0x80070005).
在访问网站的时候,出现了以上这个错误: 在网上搜了很多方法,归纳起来就如下几种: 1, 网站安全狗]的安全策略问题 解决方案: 主动防御/禁止IIS执行程序 添加"php\php-cgi.e ...