DOM API

DOM的全称是Document Object Model(文档对象模型)。
DOM是一棵树(tree),树上有Node,Node分为Document(html)、Element(元素)和Text(文本),其他不重要。

看以下图示:
object
以上是文档和对象对比图,二者通过model建立关系。Node节点示意图:
node
Node也是一个对象,其原型指向Object.prototype。
页面上所有标签都有对应的构造函数,如果页面中有注释,以上还会存在一个Comment构造函数,其原型指向Node构造函数。
Dom的主要功能是使页面中的节点通过构造函数生成对象。


一、Node接口

1、属性:

  • childNodes //会返回包括回车/空格在内的子元素,节点类型为text,及获取子节点
  • firstChild //获取第一个元素,包含空格/回车
  • innerText
  • lastChild
  • nextSibling
  • nodeName
  • nodeType
  • nodeValue
  • outerText
  • ownerDocument
  • parentElement
  • parentNode
  • previousSibling
  • textContent
    这里说明以下Node节点的几种类型:
常量 描述
Node.ELEMENT_NODE 1 一个元素节点,如<\div>和<\p>
Node.TEXT 3 Element或者Attr中的实际文字
Node.PROCESSING_INSTRUCTION_NODE 7 一个用于XML文档的ProcessingInstruction,例如<?xml-stylesheet .. ?> 声明
Node.COMMENT_NODE 8 一个 Comment节点
Node.DOCUMENT_NODE 9 一个Document节点
Node.DOCUMENT_TYPE_NODE 10 描述文档类型的DocumentType节点,如<!DOCTYPE html>就是用于HTML5的
Node.DOCUMENT_FRAGMENT_NODE 11 一个DocumentFragment节点

2、方法

  • appendChild() //添加子元素
  • cloneNOde() //复制一个节点,如果使用时cloneNode(true)则会克隆其全部子元素,否则只克隆当前标签,默认为false
  • contains() //判断一个元素是否包含另外一个元素
  • hasChildNodes() //判断一个元素是否有子元素
  • insertBefore() //将xxx插入到此节点前面
  • isEqualNode() //是否是相等的节点,这个只是两个节点看起来一样
  • isSameNode() //是否是相同的节点,这两个节点必须是同一个才为true
  • removeChild() //移除后, 此节点不会在页面中显示,但是仍保留在内存中
  • replaceNode() //替换节点
  • normalize() //常规化

以上,重点掌握innerText和textContent的区别,以及nodeType的不同类型。
1) innerText是IE开发出来的API,textContent是FF开发出来的API
2) textContent会获取所有内容,包括<style><script>标签及其内容
3) innerText会意识到样式,不会返回隐藏文本,textContent会返回
4)因为innerText受css样式影响,他会触发重排,而textConent不会,所以textContet获取会比较快
5)与textConent不同的是,在IEIE(<IE11)中对innerText进行修改,不仅会移除当前元素的节点,还会永久的破坏所有后代文本节点

二、Document接口

1、属性

  • anchors //返回当前文档中的所有锚点元素,不过目前已经被弃用。由于向后兼容,只会返回拥有name属性的a元素,而不是那些拥有id的a元素
  • body //获取body元素
  • characterSet //获取字符编码,如document.characterSet会返回”UTF-8”
  • childElementCount //获取子元素个数,如document.childElementCount返回1,因为document下是html元素,只有一个
  • children //只返回标签元素,即获取子标签,注意与childNodes区别
  • doctype
  • documentElement //html元素,文档对象的根元素
  • domain //获取域名
  • head
  • hidden //文档是否被隐藏
  • images //获取页面中所有image标签
  • links //获取页面中所有a标签
  • location //获取当前页面路径相关的所有信息包括域名、协议、路径、端口等
  • onxxxxxxx //获取当前页面所有事件,如onclick、onmouseleave等等
  • origin
  • plugins //可用于判断是否开启flash插件
  • readyState //返回页面状态,如果已经加载完,则返回”complete”
  • referrer //引荐者,即是从哪个页面跳转过来的,可在请求头中查询到
  • scripts
  • scrollingElement //正在滚动的元素,即用户正在哪个元素上滚动
  • styleSheets
  • title
  • visibilityState
  • firstElementChild //返回第一个标签元素

    2、方法

  • close() //关闭文档
  • createDocumentFragment()
  • createElement()
  • createTextNode()
  • execCommand() //执行命令,即:用户在页面选中文字,在控制台输入document.execCommand(‘copy’);则会输出选中文字内容,需检查浏览器兼容性
  • exitFullscreen()
  • getElementById()
  • getElementsByClassName()
  • getElementsByName()
  • getElementsByTagName()
  • getSelection() //获取用户选中文本
  • hasFocus()
  • open()
  • querySelector()
  • querySelectorAll()
  • registerElement()
  • write() //写
  • writeln() //写一行,会出现空格

    三、Tips

    1、请看代码:

    1
    2
    3
    4
    5
    6
    7
    8
    ......
    <div id = x></div>
    <div id = parent></div>
    ......
    <script>
    console.log(x); //x是这个id为x对应的Element的对象
    console.log(parent); //因为parent为全局变量,所以会直接输出Window,为避免这个问题,我们可以声明一个局部parent变量,然后进行赋值再输出就能够获取当前div。
    </script>

以上问题的另外一种解决方法是定义一个函数,相当于一个局部作用域,在此作用域内声明并调用parent,例:

1
2
3
4
5
6
7
<script>
function x(){
var parent = document.querySelector('parent');
console.log(parent)
}
x.call();
</script>

根据以上代码可以将上述x()方法写成立即调用形式,做法是声明一个函数然后直接调用:

1
2
3
4
function(){
var parent = document.querySelector('parent');
console.log(parent)
}.call()

以上写法在浏览器中经常报错,解决的方法有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(function(){
var parent = document.querySelector('parent');
console.log(parent)
}.call())
********或者********
(function(){
var parent = document.querySelector('parent');
console.log(parent)
}).call()
********或者********
-function(){
var parent = document.querySelector('parent');
console.log(parent)
}.call()
********或者使用+/!/~这三种符号都没问题********
********或者使用let********
{
var parent = docuemnt.querySelector('#parent');
console.log(parent); //此种写法会覆盖全局变量parent,正确写法如下:
}
{
let parent = docuemnt.querySelector('#parent');
console.log(parent); //{}+let变量构成局部作用域
}