节点层次
每段标记都可以通过 DOM 树中的一个节点表示,HTML 元素通过元素节点表示,特性( attribute ) 通过特性节点表示,文档类型通过文档类型节点表示,注释通过注释节点表示
Node 类型
DOM1级
定义了 Node 接口
,由所有 节点类型
实现,在 JS 中,其作为 Node
类型实现,除了 IE( IE8及以下版本 ),其他浏览器都可以访问到这个类型,由于所有 节点类型
都实现了该接口,所以它们共享着基本的属性和方法
nodeType
每个节点都有一个 nodeType
属性,用于表明其节点类型,由 12个数值常量表示
- 1: ELEMENT_NODE – 元素节点
- 2: ATTRIBUTE_NODE – 属性节点
- 3: TEXT_NODE – 文本节点
- 8: COMMENT_NODE – 注释节点
- 9: DOCUMENT_NODE
- 11: DOCUMENT_FRAGMENT_NODE
- 10: DOCUMENT_TYPE_NODE – 文档类型( 例如H5的 !doctype )
- 4: CDATA_SECTION_NODE
- 5: ENTITY_REFERENCE_NODE
- 7: PROCESSING_INSTRUCTION_NODE
- 6: ENTITY_NODE
- 12: NOTATION_NODE
nodeName、nodeValue
对于元素节点,nodeName
保存的是其标签名( 大写形式 ),而 nodeValue
则始终为 null
节点关系
每个节点都有一个 childNodes
属性,其保存着一个 NodeList
对象
NodeList
是一种 类数组 对象,用于保存一组有序节点,NodeList
是基于 DOM 结构动态执行查询结果的,因此 DOM 结构的变化能直接反应在 NodeList
对象中( 在获取到这个对象后改变DOM结构,该对象也会发生变化 )
访问 NodeList
中保存的节点,可以使用数组的形式访问( 方括号 ),也可以使用 item(index)
方法访问
每个节点都有一个 parentNode
属性,指向 DOM树 结构中该元素的父节点
NodeList
中的元素都是 兄弟节点 的关系,其parentNode
都指向同一个元素,兄弟节点间可以使用 previousSibling、nextSibling
两个 属性 访问 前一个 或者 后一个 兄弟节点,当没有的时候 返回 null
节点也提供了 firstChild、lastChild
两个 属性 来方便的访问 第一个 子节点 和 最后一个子节点,如果没有子节点,则 返回 null
所有节点都有一个 ownerDocument
属性,该属性指向整个文档的 文档节点
操作节点
关系指针( 节点属性的引用,例如firstChild ) 都是只读的,所以 DOM 提供了一系列操作节点的方法
可以将 DOM 树 看做是一系列指针联系起来的,任何 DOM节点 不能同时出现在文档的多个位置上
appendChild
: 用于向 childNodes
末尾添加一个节点,添加成功后,则所有有影响的节点的相应 属性( 例如父节点的 lastChild ) 指针会得到更新,然后返回新添加的节点
如果传入的节点已经是文档中的一部分了( 已经存在于文档中 ),则会将其 从原有位置删除,再添加到新位置
insertBefore
: 将节点 放在 childNodes
的某个特定位置上,接收两个参数,添加的节点和参照节点,添加成功,则添加的节点变成参照节点的 previousSibling
,如果参照节点为 null
,则和 appendChild
执行相同操作
replaceChild
: 将目标节点替换为要插入的节点,接收两个参数,添加的节点、要替换的节点,返回 被替换的节点,并且该节点从 DOM树中移除
removeChild
: 从 DOM树中移除该元素。和 replaceChild
一样,虽然节点被移除,但还是为 文档所有,只不过文档中没有该元素的位置
其他方法
下面两个方法是所有节点都有的
cloneNode
: 用于创建当前节点的副本节点,可以接收一个布尔值参数表示是否执行深度复制
深度复制会复制节点及其整个子节点树,浅复制则只会复制节点本身
该方法不会复制 JS 属性,例如事件监听等
normalize
: 唯一作用就是处理文本节点,在节点上调用该方法,则会在后代节点中查找文本节点,如果找到空本文节点,则删除,如果找到相邻的文本节点,则合并它们
Document 类型
JS 通过 Document 类型表示文档,window对象 的 document
属性 是 HTMLDocument( 继承自Document ) 的一个实例
Document节点具有以下特征:
- nodeType 是 9
- nodeName 是 #document
- nodeName 是null
- parentNode 是 null
- ownerDocument 是 null
- 子节点可能是一个 DocumentType( 最多一个 )、Element( 最多一个 )、ProcessingInstruction 或者 Comment
文档的子节点
documentElement
属性始终指向 HTML 页面中的 <html> 元素
body
属性则直接指向 页面中的 <body> 元素
文档信息
document.title
: 可以访问和改变文档的 title( 标签页上显示的文字 )
document.URL
: 当前页面的完整 URL ( 地址栏显示的URL )
document.domain
: 当前页面的域名,若是二级域名,则可以设置为 对应的一级域名,设置之后则不可以再设置回去
document.referer
: 链接到当前页面的 那个页面的URL
查找元素
getElementById
getElementByTagName( tagName )
: 通过标签名返回元素,返回一个 HTMLCollection
对象,是一个动态的集合,类似 NodeList
HTMLCollection
还有一个 namedItem()
方法,可以通过元素的 name
属性获取 集合中的元素项,也可以简写为方括号中 + 名称来访问
getElementsByName
: 返回一个 HTMLCollection
对象
特殊集合
以下属性都返回一个 HEMLCollection
对象
anchors
: 返回带 name
的 a 标签
forms
: 返回所有表单元素
images
: 返回所有图片元素
links
: 返回所有有 href
属性的 a 标签
文档写入
write
: 将参数字符串写入到文档中
writeln
: 将参数字符串在末尾加上 \n 后写入到文档中
若是在文档 加载完毕 之后再调用上述两个方法,则输出内容会将会重写整个页面
Element 类型
Element 类型用于表现 HTML、XML元素,提供了对元素标签名、子节点及属性的访问
获取元素的标签名,可以使用 nodeName
属性,也可以使用 tagName
属性,它们返回相同的值
访问属性
getAttribute( atrr )
: 获取元素上声明的名为 attr 的属性的值( 包括自定义属性,声明在元素标签上的属性 ),没有则返回 null
setAttribute( attr, value )
: 给元素设置属性名为 attr 的属性为 value 值,可以是自定义属性
自定义属性应该加上 data-
前缀以便标识
有两类特殊的属性,使用 属性 访问 和 使用 getAttribute
访问不一致,一是 style
,二是 事件函数
Text 类型
文本节点由 Text 类型表示,具有以下特征:
- nodeType 的值为 3
- nodeName 的值为 #text
- nodeValue 的值为 节点包含的字符串
- parentNode 是一个 Element
- 没有子节点
可以通过 nodeValue 或者 data 属性来访问 Text 节点的内容,并对其进行修改,修改的内容会被进行编码( 特殊字符转义 )
document.createTextNode()
: 可以创建一个文本节点
DOM 操作
应该尽量减少访问 NodeList
的次数,因为每次访问,都会进行一次基于文档的查询,可以将会多次访问的存起来?